Regex “为什么可以?”;a*a+&引用;及;(a{2,3})*a{2,3};匹配“;aaaa“;而";(a{2,3})*”;不能
我对Regex “为什么可以?”;a*a+&引用;及;(a{2,3})*a{2,3};匹配“;aaaa“;而";(a{2,3})*”;不能,regex,Regex,我对*的理解是,它消耗尽可能多的字符(贪婪地),但在必要时“回馈”。因此,在a*a+中,a*将给a+返回一个(或更多?)字符,以便匹配 但是,在(a{2,3})*中,为什么a{2,3}的第一个“实例”不给第二个“实例”一个字符,以便第二个“实例”可以匹配 此外,在(a{2,3})*a{2,3}中,第一部分似乎给了第二部分一个字符。主要问题是: 我对*的理解是,它消耗尽可能多的字符(贪婪),但在必要时“回馈” 这是完全错误的。这不是贪婪的意思 贪婪只是意味着“使用尽可能长的匹配”。它不给任何回报
*
的理解是,它消耗尽可能多的字符(贪婪地),但在必要时“回馈”。因此,在a*a+
中,a*
将给a+
返回一个(或更多?)字符,以便匹配
但是,在(a{2,3})*
中,为什么a{2,3}
的第一个“实例”不给第二个“实例”一个字符,以便第二个“实例”可以匹配
此外,在
(a{2,3})*a{2,3}
中,第一部分似乎给了第二部分一个字符。主要问题是:
我对*的理解是,它消耗尽可能多的字符(贪婪),但在必要时“回馈”
这是完全错误的。这不是贪婪的意思
贪婪只是意味着“使用尽可能长的匹配”。它不给任何回报
一旦你用这种新的理解来解释这些表达,一切都是有意义的
a*a+
-零个或多个a
,后跟一个或多个a
(a{2,3})*a{2,3}
-两个或三个a
中的零个或多个,后跟两个或三个a
(注意:要记住的关键是“零个或多个”,不匹配任何字符的第一部分被视为匹配)(a{2,3})*
-两个或三个a
中的零个或多个(这意味着在匹配三个a
s后,最后一个a
左不能匹配)解决问题的一个简单方法是将
aaaa
与regex^(A{2,3})*$
匹配
你的问题是:
在(a{2,3})*
的情况下,regex似乎没有消耗那么多
尽可能地表现个性
我建议不要在回馈角色时思考。相反,关键是接受
一旦regex接受您的字符串,匹配将结束。模式a{2,3}
仅匹配aa
或aaa
。因此,在将aaaa
与(a{2,3})*
匹配的情况下,贪婪引擎将匹配aaa
。然后,它不能匹配更多的a{2,3}
,因为只剩下一个a
。尽管正则表达式引擎能够回溯并匹配额外的a{2,3}
,但它不能aaa
现在被正则表达式接受,因此正则表达式引擎不会进行昂贵的回溯
如果在正则表达式的末尾添加一个
$
,它只会告诉正则表达式引擎部分匹配是不可接受的。此外,很容易解释接受和回溯的(a{2,3})*a{2,3}
情况。回溯仅在匹配失败时进行,但是aaa
是有效匹配,可以使用负前瞻(?!a)
来防止匹配后出现a
及
如果是这种情况,为什么
a*a+
与aaaa
匹配a*
将消耗所有四个字符,留下a+
零个字符。a*
表示零个或多个a,因此它不能匹配任何内容,a
,aa
,aaa
和aaaa
。这就是它起作用的原因。另一方面,(a{2,3})*
表示匹配两个a
或三个a
中的零个或多个。因此,它只能不匹配、aa
和aaa
。请注意,在这两种情况下,*
都不会返回任何内容。不要用回馈的方式思考,而要用如果的方式思考/else@sqd这是回溯。@iBug:在这种情况下,技术上回溯是不必要的。因为我们不匹配捕获组,所以我们可以将regexp编译成简单的状态机。你说的“不能”是什么意思?它。这应该用你正在使用的任何正则表达式的味道来标记。它肯定匹配-检查这里:
(aaa?)*
(aaa?)*(?!a)