我有一个看似简单的正则表达式但不按要求行事。要解析的输入描述如下(nb:{}不是正则表达式的一部分,只是内部的内容):
整个构造SPACE-SPACEf1是可选的
只是为了解释f1中捕获的内容: 对于第一个字符,我使用[A-Za-z]表示的字符集。其次是\ w或空格0次或更多次。这被捕获到f1。
(?:\s*-\s*(?P<f1>[A-Za-z][\w\s]*))?$
我希望以下序列匹配并将值捕获到f1:
我希望以下内容不匹配:
我希望以下匹配但不会将值捕获到f1中(我希望它不匹配但是):
这些是实际结果:
&#34; - 布鲁斯迪金森&#34; (f1 =布鲁斯迪金森)勾选;这工作
&#34;布鲁斯&#34; (f1 =未被捕获,但表达式是匹配的。这是错误的,因为Bruce与可选部分不匹配,接下来是$并不匹配Bruce)
&#34; - 布鲁斯!&#34; (f1 =不是cpatured,但表达式是匹配的;这是错误的,因为!,这意味着匹配不会出现在行尾。
我希望:
(?:\s*-\s*(?P<f1>[A-Za-z][\w\s]*))?
将消耗{ - Bruce},它应该离开!,因为下一个正则表达式令牌是$,它应该会失败;然而,电脑说不,所以我错了,但我不知道为什么:(
如果我可以让这个工作,我可以让我的表达的其余部分以我想要的方式工作。我需要别人让我不同地思考这个问题。我花了2天没有正面输出,所以非常令人沮丧。
PS:我正在使用regex101.com来测试正则表达式。正则表达式将用作Rust应用程序的一部分,其正则表达式引擎基于谷歌的RE2。
最终,我需要能够识别由&amp;分隔的一系列名称,并且整个表达式是可选的?并且必须出现在$。
行的末尾所以
和
但一步一步!
答案 0 :(得分:3)
这里的要点是你不能同时匹配和不匹配的东西。如果你使整个模式成为可选的,并且字符串的结尾是强制性的,即使没有任何感兴趣的东西,字符串的结尾也会匹配 - 总是如此。
出路是想到你感兴趣的子模式。你对这些名字很感兴趣,所以,首先要写第一个字母。在你提供的所有测试用例中,连字符似乎都是强制性的。其他一切都可以选择:
\s*-\s*(?P<f1>([^\W\d_])\w*(?:\s+\w+)*)(?:\s*&\s*(?P<f2>([^\W\d_])\w*(?:\s+\w+)*))*$
请参阅regex demo(\s
已替换为\h
,\n
已添加到否定字符类,仅用于演示目的,因为它是多行演示。)< / p>
请注意,我将[a-zA-Z]
替换为[^\W\d_]
以使模式更灵活([^\W\d_]
只匹配任何字母)。