我有一个非常基本的正则表达式,我只是不明白为什么它不起作用,所以问题分为两部分。为什么我当前的版本不起作用以及正确的表达方式是什么。
规则非常简单:
- 必须至少包含 3 个字符。
- 如果 % 字符是第一个字符,则必须至少包含 4 个字符。
因此,以下情况应按如下方式处理:
- AB——失败
- ABC-通过
- ABCDEFG-通过
- % - fail
- %AB - 失败
- %ABC - 通过
- %ABCDEFG - 通过
- %%AB - 通过
我使用的表达是:
^%?\S{3}
这对我来说意味着:
-
^
- 字符串的开头
-
%?
- 贪婪检查 0 或 1 % 字符
-
\S{3}
- 其他 3 个非空白字符
问题是,%?
由于某种原因没有进行贪心检查。它不会吃掉 % 字符(如果存在),因此“%AB”案例正在通过,我认为应该失败。为什么是%?
不吃%字符?
请有人给我带来光明:)
Edit:我使用的答案是下面的 Dav:^(%\S{3}|[^%\s]\S{2})
虽然这是一个由两部分组成的答案,但艾伦的答案确实让我明白了原因。我没用过他的版本^(?>%?)\S{3}
因为它有效,但在 javascript 实现中无效。两个很好的答案和很多帮助。
您所描述的行为的词不是greedy, it's 所有格。正常的、贪婪的量词最初会尽可能多地匹配,但如果有必要的话会后退以允许整个正则表达式匹配(我喜欢将它们视为贪婪但包容)。这就是发生在你身上的事情:%?
最初匹配前导百分号,但如果没有足够的字符来进行整体匹配,它会放弃百分号并让\S{3}
而是匹配它。
一些正则表达式风格(包括 Java 和 PHP)支持所有格量词 http://www.regular-expressions.info/possessive.html,即使这会导致整个比赛失败,也永远不会后退。 .NET 没有这些,但它有其次的东西:原子团 http://www.regular-expressions.info/atomic.html。无论您在原子组中放入什么,都像一个单独的正则表达式一样 - 它要么在应用它的位置匹配,要么不匹配,但它永远不会返回并尝试比原来更多或更少匹配,只是因为其余的正则表达式失败(也就是说,正则表达式引擎永远不会回溯into原子团)。以下是您如何使用它来解决您的问题:
^(?>%?)\S{3}
如果字符串以百分号开头,则(?>%?)
匹配它,如果没有足够的字符\S{3}
为了匹配,正则表达式失败。
请注意,正如@Dav 所证明的那样,原子组(或所有格量词)并不是解决此问题所必需的。但它们是非常强大的工具,可以轻松区分不可能的 and possible, or 太慢了 and 尽可能光滑.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)