怎么做正则表达式*和?元字符工作?

时间:2012-01-06 20:34:02

标签: regex

您好我正在使用正则表达式,但我对元字符感到困惑,特别是'*'和'?'。

'*'应该与前面的字符匹配0次或更多次。

例如,'ta * k'应该匹配'tak'和'tk'。

但我根本不会认为这是真的 - 这是我的理由:

for tak:

regexp:我需要't'

字符串:我没有

regexp:好的,你的下一个角色需要是'a'

字符串:是的

regexp:好的,继续给我角色,直到你的角色不是'a'

字符串:好的。我刚给你'k'

regexp:好的,你的下一个角色需要是'k'

字符串:我没有剩下的字符了!

regexp:失败

表示tk:

regexp:我需要't'

字符串:我没有

regexp:好的,你的下一个角色需要是'a'

字符串:不,这是'k'

regexp:失败

有人可以为我澄清为什么'tak'和'tk'匹配'ta * k'?

5 个答案:

答案 0 :(得分:1)

因为*表示“零个或多个实例”。

当“它”要求所有不是“a”的字符时,一旦它有一个,它(粗略地)将它推回到输入流中。 (或者它向前看,或者只是保留它等等)

第一个序列:这是你的第一个非"a",我会坚持到底。接下来你需要"k",这就是我所拥有的。

第二个序列:下一个字符需要是"a" - 可能是一个或多个"a"。在这种情况下,它没有。我会坚持那个非"a"。你需要一个"k"?我的"k"就在这里了。

答案 1 :(得分:1)

你是前面的一个角色:

  

regexp:好的,继续给我角色,直到你的角色不是   '一个'

     

字符串:下一个字符不是' a'

     

regexp:好的,你的下一个角色需要成为' k'

     

string:next char是' k'

所以它有效。请注意' a *'表示" 0或更多的''",而不是" 1个或更多个''""的内容。对于后者,有' +'标志,就像在' a +'。

答案 2 :(得分:1)

ta*k表示,一个't',后跟0或更多'a',后跟一个'k'。所以0'a'字符会使'tk`成为可能的匹配。

如果您想要“1或更多”而不是“0或更多”,请使用+代替*。也就是说,ta+k将匹配'tak'但不匹配'tk'。

如果有任何我没有解释的话,请告诉我。


顺便说一句,RegEx并不总是从左到右。发动机经常回溯,向前看并研究输入。它真的很复杂,这就是为什么它如此强大。如果您查看this one等网站,他们有时会解释引擎正在做什么。我推荐他们的教程,因为那是我学习RegEx的地方!

答案 3 :(得分:1)

*并不意味着匹配字符零次或多次,而 atom 匹配零次或多次。单个字符是一个原子,但任何分组都是如此。

*表示零或更多。当正则表达式光标“吞噬”t时,位置为:

in the regex: t|a*k
in the string: t|ak

然后正则表达式引擎尝试尽可能多地尝试a。这里有一个。在它吞下它后,位置是:

in the regex: ta*|k
in the string: ta|k

然后吞下k

in the regex: ta*k|
in the string: tak|

正则表达式结束,匹配。请注意,该字符串可能后面有其他字符,正则表达式引擎不关心:它有匹配。

如果字符串为tk,则在a*之前的位置为:

in the regex: t|a*k
in the string: t|k

*可以匹配一组空的a,因此a*已满足!这意味着这些职位将成为:

in the regex: ta*|k
in the string: t|k

冲洗,重复。现在,让我们将taak作为输入,将ta?k作为正则表达式:这将失败,但让我们看看如何......

# before first character
regex: |ta?k
input: |taak
# t
regex: t|a?k
input: t|aak
# a?
regex: ta?|k
input: ta|ak
# k? Oops! No...
regex: |ta?k
input: t|aak
# t? Oops! No...
regex: |ta?k
input: ta|ak
# t? Oops! No...
regex: |ta?k
input: taa|k
# t? Oops! No...
regex: |ta?k
input: taak|
# t? Oops! No... And nothing to read anymore
# FAIL

这就是为什么让正则表达式快速失败非常重要。

答案 4 :(得分:0)

要记住的基本要点是正则表达式是键入一组字符串的便捷简写。 a{1,5}只是字符串集的缩写(a,aa,aaa,aaaa,aaaaa)。 a*是([empty],a,aa,aaa,...)的简写。

因此,实际上,当您将正则表达式提供给搜索算法时,您将告诉它要搜索的字符串列表。

因此,当您向搜索算法提供ta*k时,您实际上正在为其提供字符串集(tk,tak,taak,taaak,taaaak,...)。

所以,是的,了解搜索算法的工作原理是有用的,这样你就可以提供最有效的正则表达式,但不要让尾巴摇尾巴。