正则表达式
基础知识请参考别的文章,比如MDN-js正则表达式。本文只会罗列一些不太确定的情况。
字符串和正则表达式之间的关系。
注意点
- ^
这个小可爱在[]外面表示首位的意思,比如/^h/匹配到以h开头的h。
在[]中放在首位则表示非,比如/[^abc]/匹配不是abc中任意一个的字符。
^在字符集[]是取反的意思,并且只有放在首位的时候才表示非,放在其他位置表示^字符本身
- []
. *这种特殊字符在 []字符集中不再特殊哦,比如/^[a{3}]$/匹配不了'aaa',记住只代表1个字符(\t算是1个字符)哦!/^[a{3}]$/可以匹配'a','{',3,'3','}'
Character set. This pattern type matches any one of the characters in the brackets, including escape sequences. Special characters like the dot(.) and asterisk (*) are not special inside a character set, so they don't need to be escaped. You can specify a range of characters by using a hyphen, as the following examples illustrate. The pattern [a-d], which performs the same match as [abcd], matches the 'b' in "brisket" and the 'c' in "city". The patterns /[a-z.]+/ and /[\w.]+/ match the entire string "test.i.ng".
[9-1]会怎样?
var reg = /[9-0]/;
result: VM100:1 Uncaught SyntaxError: Invalid regular expression: /[9-0]/: Range out of order in character class
at <anonymous>:1:11
复制代码
- ()
(p) 捕获 + 将p看作一个整体
(?:p) 不捕获 + 将p看作一个整体(?:p1|p2|p3)也可以。
(?=p) p前面的位置(正向先行断言lookahead)
(?!p)不是p的前面的位置(负向先行断言negated lookahead)
(?<=y)x 匹配前面是y的x
(?<!y)x 匹配前面不是y的x
分组捕获
var re = /(\w+)\s(\w+)/;
var str = 'John Smith';
var newstr = str.replace(re, '$2, $1');
console.log(newstr);
// "Smith, John"
var re = /(bar){2,3}/;
var str = 'barbarbar hellobar nobar wantabar';
str.match(re);
// ["barbarbar", "bar", index: 0, input: "barbarbar hellobar nobar wantabar", groups: undefined]
如果不想捕获但是仍然想将bar作为一个子表达式进行2~3个匹配
var re = /(?:bar){2,3}/;
var str = 'barbarbar hellobar nobar wantabar';
str.match(re);
复制代码
\w 是字符组 [0-9a-zA-Z_] 的简写形式,即 \w 是字母数字或者下划线的中任何一个字符
\b具体就是 \w 与 \W 之间的位置,也包括 \w 与 ^ 之间的位置,和 \w 与 $ 之间的位置
复制代码
- ?
匹配前面一个表达式0次或者1次。等价于 {0,1}。
出现在*, +, ?, {}后面,表示开启非贪婪模式(默认是贪婪模式)
/ab?$/.test('a'); // true
/ab?$/.test('ab'); // true
'abbbbbc'.match(/ab+?/);
// ["ab", index: 0, input: "abbbbbc", groups: undefined]
'abbbbbc'.match(/ab+/);
// ["abbbbb", index: 0, input: "abbbbbc", groups: undefined]
复制代码
js中和正则表达式相关的函数
RegExp
test
regex.test(s) 在s中是否能搜索到满足regex的内容,返回true或false。
var regex = /abc/;
var s = '123abc';
regex.test(s); // true
var regex = /abc/g;
var s = '123abc';
var s2 = 'abc';
regex.test(s); // true
regex.test(s); // false
regex.test(s); // true
regex.test(s2); // false
复制代码
s.search(regex)结果为-1,表示没有搜到,则regex.test(s)为true。如果是其他index值,表示搜索到且位置在index,则regex.test(s)为false。
如果regex是全局正则表达式,继续调用regex.test(),即使对象是不同的字符串,它还是会从新的字符串的regex.lastIndex位置开始搜索,不过你可以修改regex.lastIndex的值,或者当regext.test()返回false后,regex.lastIndex恢复为0.
exec
regex.exec(s) exec() 方法在字符串s中执行一个搜索匹配。返回一个结果数组或 null。
如果regex不是全局正则表达式,regex.lastIndex永远是0,否则,每次执行完regex.exec(s)会更新regex.lastIndex为匹配到的字符串末位的下一位(继续搜索)。
返回的数组中还有分组捕获信息哦!
该方法经常用在while中用来找到一段文字中所有匹配项,但是要小心,不要忘记两点:1、/xx/g一定是全局正则表达式 2、正则表达式不能在while中定义(while(/ab/g.exec('abc')) {})以上两种情况都可能陷入死循环。
String
以下方法的参数都是正则表达式,如果不是正则表达式,则会new RegExp(xx)完成转换。
match
s.match(regex)
返回结果
- regex不使用g标志,返回数组。(返回结果和RegExp.exec(s)相同)
[第一个匹配结果, 分组捕获$1, 分组捕获$2..., index, input, groups]
分组捕获结果:有几个就列出来几个。
index:搜索到匹配的位置。
input: 就是s,字符串的内容。
groups: 分组捕获如果有名字就显示名字,没有就显示undefined。
命名捕获分组的语法是 (?<name>...)
反向引用一个命名分组的语法是 \k<name>
在 replace() 方法的替换字符串中反向引用是用 $<name>
let str = "test1test2";
str.match(/(\w)(\w)(?<number>\d)/)
["st1", "s", "t", "1", index: 2, input: "test1test2", groups: {
"number": 1
}]
复制代码
- regex使用g标志,返回数组,数组元素为匹配到的每一项结果。(分组捕获就会忽略掉哦!)
- 没有匹配,返回null
split
不会改变字符串本身。
str.split(string|regex, limit) 当参数为正则表达式时,regex是不是全局正则表达式无所谓啦。
如果正则表达式包含至少一个捕获组,那么它将会返回一个数组,其中结果会跟捕获组互相交替。
limit: 数组元素的个数(Math.min(limit, 实际拆分后的个数))。包括分组捕获的元素。
'1ab23a5c'.split(/(\d)(\w)/);
// ["", "1", "a", "b", "2", "3", "a", "5", "c", ""]
'1ab23a5c'.split(/(\d)(\w)/, 5);
// ["", "1", "a", "b", "2"]
'abc'.split()
// ["abc"]
'abc'.split('abc')
// ["", ""]
''.split('')
// []
''.split()
// [""]
复制代码
replace
不会改变字符串本身。
str.replcace(string|regex, string | function)是不会改变str本身的哦
返回值是一个新的字符串。
regex有g标志,则替换所有匹配项,否则只替换第一个。
$1$2...代表捕获的内容
$`插入匹配左边的内容
$'插入匹配右边的内容
$$插入$
复制代码
第二个参数如果是函数,函数的参数要记住。如果regex有g,每次匹配函数都会被执行。参数参考
search
s.search(regex) 在字符串s中搜索满足regex规则的内容,如果搜到返回第一个匹配的位置,如果没搜到返回-1。
regex是不是全局正则表达式无所谓啦。
matchAll
s.matchAll(regex)
目前处于Stage 3(Canidate)阶段。
matchAll()跟批量调用exec()的工作很像,即可以获取分组捕获又不用循环,多棒!
注意点是返回的是一个迭代器,可以通过解构赋值方便使用。
regex是不是全局正则表达式无所谓啦。
唯手熟尔。
本文罗列正则表达式不太确定的情况,如^、[]、()等特殊字符的含义,还介绍了JS中和正则表达式相关的函数,包括RegExp的test、exec方法,以及String的match、split、replace等方法,说明了各方法的功能、返回值及使用注意事项。
1042

被折叠的 条评论
为什么被折叠?



