09-正则

  • .* 是贪婪模式
  • .*? 是勉强模式
  • .*+ 是侵占模式

以下是我对这几个模式的理解:

假定要分析的字符串是xfooxxxxxxfoo
模式.foo (贪婪模式):
模式分为子模式p1(.
)和子模式p2(foo)两个部分. 其中p1中的量词匹配方式使用默认方式(贪婪型)。 匹配开始时,吃入所有字符xfooxxxxxx去匹配子模式p1。匹配成功,但这样以来就没有了字符串去匹配子模式p2。本轮匹配失败;第二轮:减少p1部分的匹配量,吐出最后一个字符, 把字符串分割成xfooxxxxxxfo和o两个子字符串s1和s2。 s1匹配p1, 但s2不匹配p2。本轮匹配失败;第三轮,再次减少p1部分匹配量,吐出两个字符, 字符串被分割成xfooxxxxxxfo和oo两部分。结果同上。第四轮,再次减少p1匹配量, 字符串分割成xfooxxxxxx和foo两个部分, 这次s1/s2分别和p1/p2匹配。停止尝试,返回匹配成功。

模式.*?foo (勉强模式): 

最小匹配方式。第一次尝试匹配, p1由于是0或任意次,因此被忽略,用字符串去匹配p2,失败;第二次,读入第一个字符x, 尝试和p1匹配, 匹配成功; 字符串剩余部分fooxxxxxxfoo中前三个字符和p2也是匹配的. 因此, 停止尝试, 返回匹配成功。在这种模式下,如果对剩余字符串继续去寻找和模式相匹配的子字符串,还会找到字符串末尾的另一个xfoo,而在贪婪模式下,由于第一次匹配成功的子串就已经是所有字符,因此不存在第二个匹配子串。

模式.*+foo (侵占模式): 

也叫占用模式。匹配开始时读入所有字符串, 和p1匹配成功, 但没有剩余字符串去和p2匹配。因此, 匹配失败。返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'xfooxxxxxxfoo'.match(/.*foo/g)
["xfooxxxxxxfoo"]

'xfooxxxxxxfoo'.match(/.*?foo/g)
["xfoo", "xxxxxxfoo"]

'xfooxxxxxxfoo'.match(/.*+foo/)
报错

'232hjdhfd7474$'.match(/\w+[a-z]/g)
["232hjdhfd"]

'232hjdhfd7474$'.match(/\w++[a-z]/g)
报错