量词
量词是正则表达式的灵魂,也是正则表达式具有强大的文本处理能力的核心原因。常见的量词包括:
量词 | 含义 |
---|---|
* | 匹配0次或多次 |
| 匹配一次或多次 |
? | 匹配0次或一次 |
{m, n} | 匹配m次到n次 |
量词作用于左侧最近的一个字符。下式含义是将类似于abccc
的字符序列替换为字符序列abc
,即去掉末尾多余的c
。注意量词作用于c
,要让量词作用于abc
,可以加括号,如(abc)
。
$content =~ s/abc /abc/g;
匹配优先
正则表达式(.*)(.*)
匹配文本abcdef
,应该是什么结果?答案是第一个.*
匹配了全部文本,第二个.*
什么都没匹配到。
出现这样的结果是因为量词匹配默认是匹配优先的,它会尽量多匹配字符,仅在匹配失败的时候进行回溯。如果正则表达式是(.*)(. )
,第一个.*
匹配abcde
,第二个.
匹配f
。匹配的过程是,第一个.*
先匹配了所有文本,到.
匹配的时候没有文本了,这次的匹配会失败,然后会发生回溯,.*
退回一个字符f
,然后.
匹配了字符f
,正则表达式匹配成功。
默认匹配优先是很有好处的,符合正常的直觉。它使得我们可以用.*
来匹配所有文本。但某些时候我们需要改变这种默认行为。
非匹配优先
量词 | 含义 |
---|---|
*? | 匹配0次或多次 |
? | 匹配一次或多次 |
?? | 匹配0次或一次 |
{m, n}? | 匹配m次到n次 |
在量词后加个?
可以使量词变成非匹配优先。这个时候量词会尽量少的匹配字符,仅在匹配失败的时候匹配更多的字符。正则表达式(.*?)(.*?)
匹配文本abcdef
,结果是两个.*?
都匹配为空,匹配都为0次,这个时候正则表达式匹配成功。正则表达式(.*?)f
匹配文本abcdef
,结果是.*?
匹配abcde
,匹配过程是.*?
先匹配0次,f
不匹配a
,匹配失败,.*?
匹配一次,f
不匹配b
,匹配失败。一直到.*?
匹配abcde
,f
匹配f
,匹配成功。
占有优先
量词 | 含义 |
---|---|
* | 匹配0次或多次 |
| 匹配一次或多次 |
? | 匹配0次或一次 |
{m, n} | 匹配m次到n次 |
在量词后加个
可以使量词变成占有优先匹配,它是不保存状态的匹配,也就是说无法回溯。
正则表达式(.* )(. )
匹配文本abcdef
,会匹配失败,.*
匹配了所有文本,.
无法匹配,而且因为没有状态保存,无法回溯,所以匹配失败。
条件结构
量词?
属于条件结构的一种,表示可选的匹配(0次或一次)。另一个条件结构是|
,语义是或。a|b
表示匹配a
或者b
。下式表示把abc
或者abd
替换为空(删除)。
$content =~ s/abc|abd//g;
|
优先级很低,所以上式是abc
或abd
而不是c
或a
。