转义字符
- 转义符号
\
- 转义字符
\字符
- 想用单引号包裹单引号,可以转义
\'
let str = '你非常\'优秀\'';
console.log(str); // 你非常'优秀'
- 如果想显示
\
,可以转义\\
let str = '你非常\\优秀\\';
console.log(str); // 你非常\优秀\
- 一些规定好的转义字符:
\n
换行;\t
制表符;\r
回车
正则表达式
- 正则表达式是字符串的一种匹配模式,为简化字符串操作而生
- 说白了就是检索字符串中特定字符的规则
- 正则并不是单纯的字符串,而是一种逻辑公式
创建正则表达式
1. 构造函数创建:
let reg = new RegExp();
JS 提供了一个内置构造函数 RegExp()
(regular expression),用来创建正则表达式
let reg = new RegExp(); // 实例化一个正则对象
console.log(reg); // /(?:)/
- 参数1:正则的规则
- 参数2:修饰符
i
m
g
let reg = new RegExp('text');
let str1 = 'This is a text';
let str2 = 'This is a apple';
console.log(reg.test(str1), reg.test(str2)); // true false
-
test()
→ 判断字符串中,是否包含匹配正则的子字符串 - 在该例中的效果,类似
includes()
2. 字面创建:
let reg = //;
let reg = /text/;
let str1 = 'This is a text';
let str2 = 'This is a apple';
console.log(reg.test(str1), reg.test(str2)); // true false
特殊情况
- 一般情况下,推荐使用字面量创建
- 但对于字符串变量,只能使用构造函数创建
let str = 'text';
let reg1 = /str/; // /str/
let reg2 = new RegExp(str); // /text/
正则的方法
test()
用于判断字符串参数,是否有匹配正则规则的子字符串
- 格式:
reg.test(str);
-
str
:需要判断的字符串 - 返回布尔值,匹配成功返回
true
,否则返回false
let reg = /super/;
let str = 'hello superman';
console.log(reg.test(str)); // true
exec()
不管是不是全局匹配,都只在 str
中进行一次匹配,提取匹配成功的子字符串
- 格式:
reg.exec(str);
-
str
:需要查询的字符串 - 返回一个数组,存放与匹配文本有关的信息;如果没有找到匹配的文本,则返回
null
let reg = /super/;
let str = 'hello superman superman aaa';
let result = reg.exec(str);
console.log(result);
// ["super", index: 6, input: "hello superman superman aaa", groups: undefined]
-
result[0]
:匹配文本 -
result.index
:匹配文本的首字符的位置 -
result.input
:被检索的字符串str
字符串的方法
字符串的
match()
方法
match()
将检索字符串 str
,寻找 1~ n 个与 reg
匹配的文本;并返回指定的值
- 如果
reg
没有g
与 reg.exec(str);
等效
let reg = /super/;let str = 'hello superman superman aaa';let result = str.match(reg);console.log(result);// ["super", index: 6, input: "hello superman superman aaa", groups: undefined]
- 如果
reg
有g
match()
方法将执行全局检索,找到 str
中的所有匹配子字符串。
- 返回值
result
:若没有找到任何匹配的子串,则返回null
;否则,返回一个数组,存放所有的匹配子串,而没有index
/input
属性
let reg = /super/g;let str = 'hello superman superman aaa';let result = str.match(reg);console.log(result); // ["super", "super"]
字符串的
search()
方法
从前往后查询指定字符串第一次出现的位置 ( 1个参数 )
let reg = /super/;let str = 'hello superman superman aaa';console.log(str.search(reg)); // 6
字符串的
split()
方法
字符串 → 数组
let reg = /super/;let str = 'hello superman superman aaa';console.log(str.split(reg)); // ["hello ", "man ", "man aaa"]
字符串的
replace()
方法
实现字符串的替换
let reg = /man/g; // 后面加 g,可以实现全部替换let str = 'hello superman superman aaa';console.log(str.replace(reg, 'women')); // hello superwomen superwomen aaa
修饰符
-
i
:不区分大小写ignoreCase
-
m
:换行匹配multiline
-
g
:全局匹配global
i
:不区分大小写ignoreCase
默认区分大小写
let reg = /Text/;
let str = 'This is a text';
console.log(reg.test(str)); // false
let reg = /Text/i; // 字面量写法
let str = 'This is a text';
console.log(reg.test(str)); // true
m
:换行匹配multiLine
默认不是换行匹配
let reg = new RegExp('^Text');
let str = 'This is a \nText and';
console.log(str.match(reg)); // null
let reg = new RegExp('^Text', 'm'); // 构造函数写法
let str = 'This is a \nText and';
console.log(reg.exec(str));
// ["Text", index: 11, input: "This is a \nText and", groups: undefined]
g
:全局匹配global
默认只匹配一个
let reg = new RegExp('text');
let str = 'This is a text and text and text';
console.log(str.match(reg));
// ["text", index: 10, input: "This is a text and text and text", groups: undefined]
let reg = new RegExp('text', 'g');
let str = 'This is a text and text and text';
console.log(str.match(reg));
// ["text", "text", "text"]
特殊语法
特殊字符
- 正则表达式 = 普通字符 + 特殊字符(元字符)
- 普通字符:
字母
(abcABC)、数字
(123)、_
、$
- 特殊字符:
()
、[]
、{}
、^
、$
、*
、?
、\
、|
、+
、.
… - 普通字符可以直接使用
- 特殊字符要转义,因为特殊字符在正则中有特殊意义
// 匹配 ^a
let reg = /\^a/g; // ^ 有特殊意义,需要转义
let str = 'bb^acc';
console.log(str.match(reg)) // ["^a"]
预定义的特殊字符
-
\t
:制表符 -
\n
:回车符 -
\f
:换页符 -
\b
:回退字符
// 匹配制表符
let str = 'a\tb';
let reg = /\t/;
console.log(str); // a b
console.log(reg.test(str)); // true
// 匹配回车符
let str = `a\nb`;
let reg = /\n/;
console.log(str)
console.log(reg.test(str)); // true
字符集
简单类
通过 []
包裹住,来表示这几个字母组成的一个简单集合
如:[abDF45]
表示由 abDF45
6 个字符组成的一个集合
let str = 'abcdefg';
let reg = /[bgk]/;
console.log(str.match(reg));
// ["b", index: 1, input: "abcdefg", groups: undefined]
在 str
中,找到第 1 个在集合 [bgk]
中的字符
范围类
通过 小字符-大字符
组成的一个范围集合;大小指的是 ASCII 码大小
如:[a-z]
表示小写字母集合、[A-Z]
表示大写字母集合、[0-9]
表示数字集合
let str = 'abcdefg';
let reg = /[f-i]/g;
console.log(str.match(reg)); // ["f", "g"]
要按照字符编码集从小到大写,eg:[A-z]
;不能从大到小写,eg:[a-Z]
负向类
在 []
内部添加 ^
前缀,表示不包含该集合的字符集
如:[^abc]
表示不包含 abc
的集合,[^ab89CD]
表示不包含 ab89CD
这 6 个字符的集合
let str = 'abcdef';
let reg = /[^abc]/g;
console.log(str.match(reg)); // ["d", "e", "f"]
组合类
将几个集合拼接在一起,表示一个组合的集合
如:[a-zA-Z0-9]
表示大小写字母以及数字的集合
let str = '0';
let reg = /[0-9a-z]/;
console.log(reg.test(str)); // true
注意
- 在
[]
内,无论写多少个字符,只会匹配其中一个 - 特殊的字符集:
[\u4e00-\u9fa5]
表示中文集
界定符
字符串有边界,这里的边界指的就是字符串的首尾
判断前后缀
判断前缀用 ^
,如:/^abc/
判断字符串的前缀是否为 abc
判断后缀用 $
,如:/xyz$/
判断字符串的后缀是否为 xyz
let str = 'sdf';
let reg = /^b/;
console.log(reg.test(str)); // false
匹配后面跟的字符
(?=n)
:匹配到后面跟着字符 n
的字符串
(?!n)
:匹配到后面没有紧跟着字符 n
的字符串
let str = "abcd";
let reg = /c(?=d)/; // 找到后面跟着 d 的字符 c
console.log(str.match(reg));
// ["c", index: 2, input: "abcd", groups: undefined]
预定义的类(元字符)
就是特殊的转义字符,把一些字母转成特殊意义的字符
-
.
→[^\n\r]
:除了换行和回车之外的任意字符 -
\d
→[0-9]
:数字字符( digit 数字 ) -
\D
→[^0-9]
:非数字字符 -
\s
→[\t\n\f\r]
:空白字符 -
\S
→[^\t\n\f\r]
:非空白字符 -
\w
→[a-zA-Z_0-9]
:字母 -
\W
→[^a-zA-Z_0-9]
:非字母
let str = 'sdf';
let reg = /\W/;
console.log(reg.test(str)); // false
量词
-
用于设置匹配到字符的个数
-
默认贪婪匹配,即尽量往指定范围大的匹配;在量词后加
?
,则变为惰性匹配,即尽量往指定范围小的匹配 -
重复书写某个规则时,可以用量词代替。eg:匹配 10 个数字,
/\d\d\d\d\d\d\d\d\d\d/
→/\d{10}/
量词普通写法
-
{n}
:n 个 -
{n,m}
:n ~ m 个,[n, m],是个闭区间 -
{n,}
:n ~ 无穷大个,包含 n
let str = 'a b a bb a bbb a bbbb';
let reg1 = /b{2,4}/g; // 贪婪匹配
let result1 = str.match(reg1);
console.log(result1); // ["bb", "bbb", "bbbb"]
let reg2 = /b{2,4}?/g; // 惰性匹配
let result2 = str.match(reg2);
console.log(result2); // ["bb", "bb", "bb", "bb"]
量词特殊写法
-
{0,1}
→?
-
{0,}
→*
-
{1,}
→+
let str = 'ababba';
let reg1 = /b?/g;
let result1 = str.match(reg1);
console.log(result1); // ["", "b", "", "b", "b", "", ""]
let reg2 = /b*/g;
let result2 = str.match(reg2);
console.log(result2); // ["", "b", "", "bb", "", ""]
let reg3 = /b+/g;
let result3 = str.match(reg3);
console.log(result3); // ["b", "bb"]
子项
可以用 ()
将部分正则括住,这样在使用 match
/ exec
做匹配时,能获取指定字符开头的数据
let str = "abcd12ef";
let reg = /d(\d+)/; // 获取 d 后面的数字
let result = str.match(reg);
console.log(result); // ["d12", "12", index: 3, input: "abcd12ef", groups: undefined]
console.log(result[1]); // 12
注意:加全局匹配 g
后,match
方法就不包含子项了
子项的反引用
格式:\num
;num
为子项的序号
let str = "ccsdbbcc99d";
let reg = /([a-z])\1/g; // 获取连续写了两遍的字母
let result = str.match(reg);
console.log(result); // ["cc", "bb", "cc"]
上面 \1
表示复用第 1 个子项 [a-z]
或者 |
- 在正则中,
|
表示或者
let str = "adcd12ef";
let reg = /ad|cd/g;
console.log(str.match(reg)); // ["ad","cd"]
可以与子项结合使用:
let str = "adcd12ef";
let reg = /(a|c)d/g;
console.log(str.match(reg)); // ["ad","cd"]
- 如果
|
放在字符集里,表示普通的竖线
let str = "adcd1|d2ef";
let reg = /[a|c]d/g;
console.log(str.match(reg)); // ["ad", "cd", "|d"]
[a|c]
表示 a
、|
、b
中的一个
案例
- 手机号:11位、第一位是1、都是数字
let reg = /^1\d{10}$/;
let str = prompt('请输入手机号');
if (reg.test(str)) {
console.log('成功');
} else {
console.log('失败');
}
- QQ 邮箱:
let eMail = /^\d{6-10}@q{2}\.com$/;
.
在正则中有特殊意义,所以需要转义
- 日期格式转换:
function formatDate(date, fmt) {
// 年
let reg = /Y+/;
if (reg.test(fmt)) {
let str = fmt.match(reg)[0];
fmt = fmt.replace(str, (date.getFullYear() + '').substr(4 - str.length));
}
// 月日时分秒
let obj = {
'M+': date.getMonth() + 1,
'D+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
}
for (let key in obj) {
let reg = new RegExp(key);
if (reg.test(fmt)) {
let str = fmt.match(reg)[0];
fmt = fmt.replace(str, toTwo(obj[key]));
}
}
return fmt;
}
function toTwo(num) {
return (num > 10 ? '' : '0') + num;
}
let date = new Date();
let result = formatDate(date, 'YYYY-MM-DD hh:mm:ss');
console.log(result);