WebGL Tutorial
and more

字符数量

撰写时间:2024-03-01

修订时间:2024-03-05

概述

本章学习如何匹配特定数量的字符。对于专门用于指定数量的格式,我们统称为量词。通过限定量词,我们的匹配结果更加精准。

x* : 0或多

x*来匹配0或多个x字符。

const src = `a3c a25c abbbc a_c ac`; let re = /a\d*c/g;

如果字符ac之间有0或多个数字,则匹配成功。

x+ : 1或多

x+来匹配1或多个x字符。

const src = `a3c a25c abbbc a_c ac`; let re = /a\d+c/g;

如果字符ac之间有1或多个数字,则匹配成功。

x? : 0或1

x?来匹配0或1个x字符。

const src = `a3c a25c abbbc a_c ac`; let re = /a\d?c/g;

如果字符ac之间有0或1个数字,则匹配成功。

x{n} : 连续出现n次

x{n}来匹配连续出现的n个x字符。

const src = `a3c a25c abbbc a_c ac`; let re = /b{3}/g;

如果字符b连续出现3次,则匹配成功。

x{n,} : 连续出现至少n次

x{n}来匹配连续出现至少n个x的字符。

const src = `a3c a25c abbbc a_c ac bbcc`; let re = /b{2,}/g;

如果字符b连续出现至少2次,则匹配成功。

x{n,m} : 连续出现至少n次,至多m次

x{n,m}来匹配连续出现至少n个,至多m个x的字符。

const src = `ba a25c abbbc a_c ac bbcc bbbbe`; let re = /b{2,3}/g;

如果字符b连续出现2到3次,则匹配成功。

数量表达式? : 非贪婪的数量匹配

何谓贪婪

上面的几种数量表达式是贪婪的greedy)。我们用例子说明。

const src = `

one

two

`; let re = /

.+

/g;

上面的文本输入源中,共有2个p标签。每个p标签都以<p>...</p>的开始与结尾的形式构成。我们先设定匹配模式为:

/

.+

/g

本意是要求每次匹配,都要匹配出每对p标签内的内容。因为共有2对p标签,因此应成功匹配2次。如下图所示:

digraph { edge [colorscheme=set312] src [shape=plaintext, colorscheme=greens9, label=<
srcTAG_START{p}oneTAG_END{p}TAG_START{p}twoTAG_END{p}
>] src:f1 -> src:f2 [label="1st" dir=both]; src:f3 -> src:f4 [label="2nd" dir=both]; }

从实际匹配结果来看,确实是匹配了。但实际上该匹配结果不符合我们的要求。我们可以查看网页上匹配结果的HTML代码:

<p>one</p><p>two</p>

每匹配成功一次,应自动生成一个span标签。而上面只生成了一个span标签,说明只匹配了1次。并且,在这仅有的一次匹配中,将两个p标签的内容都一并匹配进去了。

<p>one</p><p>two</p>

其示意图如下:

digraph { edge [colorscheme=set312] src [shape=plaintext, colorscheme=greens9, label=<
srcTAG_START{p}oneTAG_END{p}TAG_START{p}twoTAG_END{p}
>] src:f1 -> src:f4 [label="1st" dir=both]; }

如图所示,前后有两个</p>,无论匹配哪一个,都符合我们所指定的匹配要求。在这种情况下,正则表达式引擎被设定为默认情况下是贪婪的,即它会匹配最远的、最多的内容。显然,这个默认设置不符合我们这里的要求。

如何改为非贪婪

我们可以改变这种默认设置,方式是在数量表达式.+之后加上一个?号,数量表达式变为.+?,则可令正则表达式不要贪婪。在最小范围内,一旦匹配成功,应立即返回一个结果;然后再接着匹配剩余部分;若再有匹配结果,则应再返回另外的结果。

const src = `

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}?

贪婪或非贪婪,本无对错之分,在不同的场合都有可能应用得上。我们学习了相应的语法后,根据特定需求灵活选用即可。

参考资源

  1. ECMA 262: RegExp Objects
  2. MDN: Regular expressions