您好我正在使用正则表达式,但我对元字符感到困惑,特别是'*'和'?'。
'*'应该与前面的字符匹配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'?
答案 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,...)。
所以,是的,了解搜索算法的工作原理是有用的,这样你就可以提供最有效的正则表达式,但不要让尾巴摇尾巴。