字符数量
撰写时间:2024-03-01
修订时间:2024-03-05
概述
本章学习如何匹配特定数量的字符。对于专门用于指定数量的格式,我们统称为量词。通过限定量词,我们的匹配结果更加精准。
x* : 0或多
用x*
来匹配0或多个x
字符。
如果字符a
与c
之间有0或多个数字,则匹配成功。
x+ : 1或多
用x+
来匹配1或多个x
字符。
如果字符a
与c
之间有1或多个数字,则匹配成功。
x? : 0或1
用x?
来匹配0或1个x
字符。
如果字符a
与c
之间有0或1个数字,则匹配成功。
x{n} : 连续出现n次
用x{n}
来匹配连续出现的n个x
字符。
如果字符b
连续出现3次,则匹配成功。
x{n,} : 连续出现至少n次
用x{n}
来匹配连续出现至少n个x
的字符。
如果字符b
连续出现至少2次,则匹配成功。
x{n,m} : 连续出现至少n次,至多m次
用x{n,m}
来匹配连续出现至少n个,至多m个x
的字符。
如果字符b
连续出现2到3次,则匹配成功。
数量表达式? : 非贪婪的数量匹配
何谓贪婪
上面的几种数量表达式是贪婪的(greedy)。我们用例子说明。
one
two
`; let re = /.+
/g;上面的文本输入源中,共有2个p标签。每个p标签都以<p>...</p>
的开始与结尾的形式构成。我们先设定匹配模式为:
.+
/g本意是要求每次匹配,都要匹配出每对p标签内的内容。因为共有2对p标签,因此应成功匹配2次。如下图所示:
src | TAG_START{p} | one | TAG_END{p} | TAG_START{p} | two | TAG_END{p} |
从实际匹配结果来看,确实是匹配了。但实际上该匹配结果不符合我们的要求。我们可以查看网页上匹配结果的HTML代码:
<p>one</p><p>two</p>
每匹配成功一次,应自动生成一个span标签。而上面只生成了一个span标签,说明只匹配了1次。并且,在这仅有的一次匹配中,将两个p标签的内容都一并匹配进去了。
其示意图如下:
src | TAG_START{p} | one | TAG_END{p} | TAG_START{p} | two | TAG_END{p} |
如图所示,前后有两个</p>
,无论匹配哪一个,都符合我们所指定的匹配要求。在这种情况下,正则表达式引擎被设定为默认情况下是贪婪的,即它会匹配最远的、最多的内容。显然,这个默认设置不符合我们这里的要求。
如何改为非贪婪
我们可以改变这种默认设置,方式是在数量表达式.+
之后加上一个?
号,数量表达式变为.+?
,则可令正则表达式不要贪婪。在最小范围内,一旦匹配成功,应立即返回一个结果;然后再接着匹配剩余部分;若再有匹配结果,则应再返回另外的结果。
one
two
`; let re = /.+?
/g; // non-greedy现在,分别匹配出了2个结果,每个<p>
都匹配了最近的</p>
。
这种要求非贪婪的作法在匹配成对的HTML标签时最为常见。
各种量词的非贪婪的格式
各种量词均有对应的非贪婪的语法,且都是在量词的后面直接加上?
即可。
量词 | 对应的非贪婪量词 |
---|---|
x* | x*? |
x+ | x+? |
x? | x?? |
x{n} | x{n}? |
x{n,} | x{n,}? |
x{n,m} | x{n,m}? |
贪婪或非贪婪,本无对错之分,在不同的场合都有可能应用得上。我们学习了相应的语法后,根据特定需求灵活选用即可。