第一章
行的起始和结束
^
,$
字符组
匹配若干字符之一,在字符组内部,字符组元字符‘-’(连字符)表示一个范围。(只有在字符组内部,连字符才是元字符)。在字符组内部,.和?被当作普通字符。
排除型字符组
[^...]表示匹配一个未列出的字符
用点号匹配任意字符
元字符.
是用来匹配单个任意字符的字符组的简便写法。如果我们需要在表达式中使用一个“匹配任何字符”的占位符,用点号就很方便。
多选结构
匹配任意子表达式。例如书里的gr(e|a)y
,通过括号来划定多选结构的范围。多选结构比字符组优的地方在于它可以匹配任意长度的文本。
忽略大小写
参数i表示忽略大小写,i称作“修饰符”,修饰符其实不是正则表达式里的一部分,但编程语言里一般都会提供这样的修饰符,另外还有g
。
单词边界符
<
和>
匹配单词分界的位置,用来匹配单词的开头和结尾部分。但<
和>
并不是元字符,只有当它们与斜线结合起来的时候,整个序列才具有特殊意义。在js中,表示一个单词边界,也就是单词和空格之间的位置。
可选项元素
元字符?
代表可选项,把它加到一个字符的后面,就表示此处容许出现这个字符,不过它的出现并非匹配成功的必要条件。比如我们想要匹配7月4日(July fourth)的文本,其中月份可能写作July或Jul,而日期可能写作fourth,4th 或者是4。我们可以用July?.(fourth|4(th)?)
来匹配。
其他量词:重复出现
元字符+
表示“之前相邻的元素出现一次或多次”,*
表示“之前相邻的字符出现任意多次或者不出现”。加号,问号和星号这三个元字符,统称为量词。举例来说:.?
能够匹配一个可能出现的空格,.*
能够匹配任意多个空格,.+
能够确保至少有一个空格。
规定出现次数的范围:区间
{min, max}
括号及反向引用
在前面我们遇到了括号的两种作用:限制多选项的范围,将若干字符组合为一个单元。现在要介绍另一种用途:括号能够记忆其中的子表达式匹配的文本。在匹配the"the
的时候,我们就可以用<([A-Za-z]+)"+1>
。比如我们想查询一段文本里所有可能出现的重复单词,我们可以先匹配任意一个单词,接下来利用反向引用检查“后面的单词是否与它一样”。
'hello, World world'.match(/([a-z]+) +1/gi)
在浏览器控制台里测试一下吧。
但是这个表达式仍有它的局限性,它会把每一行文字都当作一个独立部分来看待,所以如果单词重复的第一个单词在某行末尾,第二个单词在下一行的开头,这个表达式就无法找到。
神奇的转义
如果我们想匹配元字符,比如:.,?,(,...呢?我们可以在这些元字符前面加上反斜线,这里的反斜线称为“转义符”——它作用的元字符会失去特殊含义,成了普通字符。
example
编写正则表达式,我们不仅需要去考虑哪些匹配的情况,还需要去考虑怎么样排除不匹配的情况。
例如:匹配12小时制时刻的文字(9:17 am)或(12:30 pm)
考虑:小时数情况:(1[012]|[1-9])
;分钟情况:[0-5][0-9]
;所以合起来就是:(1[012]|[1-9]:[0-5][0-9] (am|pm)
。
思考:怎么匹配24小时制的时间?(提示:时刻部分:0?[0-9]|1[0-9]|2[0-3]
,前面的也可以合并一下:[01]?[0-9]|2[0-3]
)
子表达式
“子表达式”指的是整个正则表达式中的一部分,通常是括号内的表达式,或者是由|分隔的多选分支,或是单个字符。注意:量词作用的对象是它们之前紧邻的子表达式,所以mis+pell
中的+作用的是s,而不是mis
。
第二章
用s
来匹配所有空白,另外正则表达式里还提供了许多有用的“简记法”。例如:S, w, W, d, D
等等
非捕获型括号
在上一章中,利用捕获型括号,可以很容易地取到前面已经匹配到的分组,但有时候我们不需要捕获这个分组,比如书中提到的温度转换的这个例子(/^([-+]?[0-9]+(?:.[0-9]*)?))s*([CF])$/
),(?:...)
表示只分组不捕获。
替换
有的时候我们想要利用正则表达式来替换文本中的一些字符。js中String类有个replace()方法,下面的例子就用这个方法做演示:
1:将浮点数做一下转化(保留小数点后两位数字,如果第三位不为零,也需要保留。)例如:12.3750000000392修正为12.375,37.500修正为37.50。
var num1 = "12.3750000000392";
num1.replace(/(d*)(.dd[1-9]?)d*/, '$1$2') //12.375