JS正则表达式必知必会

JS正则表达式包含非/贪婪匹配、反向引用、反向/预搜索、匹配次数、特殊转义等概念。

转义字符

\A

匹配字符串起始位置。

\Z

匹配字符串结束位置。

\b

匹配一个单词边界。

\d

匹配一个数字。

\D

与\d相反,所有非数字。

\s

匹配空白字符。

\S

与\s相反,所有非空白字符。

\w

任意单个字符。

\W

与\w相反,非字母数字。

\cx 

匹配由x指明的控制字符,如:

\cM 

匹配一个Control-M或回车符,x的值须为A-Z或 a-z其中之一。否则,将c视为原义 'c' 字符。

\f

匹配一个换页符,等价于 \x0c 和 \cL。

\n

匹配一个换行符,等价于 \x0a 和 \cJ。

\r

匹配一个回车符,与\x0d、\cM等价。

\t

匹配一个制表符,与\x09、\cI等价。

\v

匹配一个垂直制表符,与\x0b、\cK等价。

贪婪匹配

/<.*>/

表达式匹配从小于号 (<) 到大于号 (>) 间的所有内容。

非贪婪匹配

/<.*?>/

只检出开始和结束间的第一次匹配。

反向引用

表达式在作匹配时,表达式引擎将小括号 “( )”内表达式匹配到的字符串记录下来。

在获取匹配结果时,小括号内表达式匹配到的字符串可单独取出。

“\1”

引用第1对括号内匹配到的字符串,

”\2” 

引用第2对括号内匹配到的字符串……以此类推。 若一对括号内包含另一对括号,则外层括号先排序号。

换句话说,哪一对的左括号 “(“ 在前,那这一对为先。

在如下正则中:

(.+)\1

\1等于(.+)匹配到的值,也就是连续2次出现的值。

重复字符/单词

"Is is the cost of of gasoline going up up".match(/\b([a-z]+) \1\b/ig);

表达式 :

('|")(.*?)(\1)

在匹配'Hello', "World"时,匹配结果是:成功;

匹配到的内容是:'Hello'。

再次匹配下一个时,可匹配到 "World"。

表达式:

(\w)\1{4,}

在匹配"aa bbbb abcdefg ccccc 111121111 999999999" 时,

匹配结果是:成功;

匹配的内容是 "ccccc"。

再次匹配下一个,将得到999999999。

表达式要求 "\w"范围的字符至少重复5次,点击测试 注意与 "\w{5,}" 间的区别。

表达式:

<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?</\1>

在匹配如下内容时:

<td id='td1' style="bgcolor:white"></td>

匹配结果是成功。

如果<td>与</td>不成对,则匹配失败;

改成其他成对标签,也可匹配成功。

预搜索、不匹配,反向预搜索、不匹配

抽象的特殊符号:

^、$、\b

都有一个共同点,本身不匹配任何字符,只对 "字符串的开始与结束"或"字符间的缝隙"附加了一个条件。

理解这个概念后,将继续了解另外一种对"两头"或"缝隙"附加条件更灵活的表示方法。

正向预搜索

(?=xxxxx),(?!xxxxx)
格式:(?=xxxxx)

匹配的字符串时,对所处的"缝隙"或"两头"附加条件:

所在缝隙的右侧,须能够匹配上xxxxx这部分表达式。

因为在此处它作为这个缝隙上附加的条件,所以,并不影响后续表达式去匹配缝隙后的字符。

类似\b本身不匹配任何字符。

\b只将所在缝隙之前、之后的字符取来执行一下判断,不会影响后续表达式的匹配。

表达式 "Windows (?=NT|XP)"

在匹配"Windows 98、Windows NT、Windows 2000" 时,只匹配"Windows NT"中的"Windows",其他"Windows"字样不被匹配。

表达式:

(\w)((?=\1\1\1)(\1))+

字符串:

aaa ffffff 999999999

将匹配6个"f"的前4个。

匹配9个"9"的前7个。

这个表达式可读解成:

重复4次以上的字母数字,则匹配最后2位之前的部分。

当然,这个表达式可以不这样写,此处只作为演示。

格式:

(?!xxxxx)

所在缝隙右侧,必须不能匹配xxxxx这部分表达式。

表达式:

((?!\bstop\b).)+

匹配如下内容时

fdjka ljfdl stop fjdsla fdj

将从头匹配到"stop"前的位置,若字符串中没有"stop",则匹配整个字符串。

表达式:

do(?!\w)

匹配如下内容时:

done, do, dog

只能匹配 "do"。

"do"后边使用"(?!\w)"和用"\b"效果一样。

反向预搜索

(?<=xxxxx),(?<!xxxxx)

两种格式的概念与正向预搜索类似。

反向预搜索要求:所在缝隙的"左侧",两种格式分别要能够匹配或必须不能够匹配指定表达式,而不是去判断右侧。

与"正向预搜索"一样:

它们都是对缝隙的一种附加条件,本身不匹配任何字符。

表达式:

(?<=\d{4})\d+(?=\d{4})

匹配如下内容时:

1234567890123456

将匹配除前4个数字和后4个数字之外的中间8个数字。

JScript.RegExp不支持反向预搜索。

修饰匹配次数

无论只能匹配一种字符的表达式,还是匹配多种字符中任意一个的表达式,都只能匹配一次。

若使用表达式再加上修饰匹配次数的特殊符号,则无需重复书写表达式即可拥有重复匹配的能力。

使用方法

"次数修饰"放在"被修饰表达式"后边。如:

[bcd][bcd]

可写成

[bcd]{2}

{n}表达式重复n次,如:

\w{2}

相当于

\w\w

表达式:

a{5}

相当于

aaaaa

表达式:

{m,n}

表达式至少重复m次,最多重复n次,如:

ba{1,3}

匹配"ba"、"baa"、"baaa"。

{m,}

至少重复m次,如:

\w\d{2,}

匹配"a12"、"_456"、"M12344"...

?

匹配0次或者1次,相当于 {0,1},如:

a[cd]?

匹配 "a","ac","ad"

+

至少出现1次,相当于 {1,},如:

a+b

匹配"ab","aab","aaab"...

*

表达式不出现或出现任意次,相当于

{0,}

如:

\^*b

匹配 "b","^^^b"...