RE2(Rust)正则表达式没有按预期工作

时间:2016-04-27 12:43:13

标签: regex rust

我有一个看似简单的正则表达式但不按要求行事。要解析的输入描述如下(nb:{}不是正则表达式的一部分,只是内部的内容):

  • 0个或更多空格{\ s *}
  • 的序列
  • 短划线{ - }
  • 0个或更多空格{\ s *}
  • 的序列
  • 一个完整的人的名字(名字,中间名,姓氏;全部被捕获到f1)。名称不能以数字开头 必须出现在行的末尾{[A-Za-z] [\ w \ s] *)}

整个构造SPACE-SPACEf1是可选的

只是为了解释f1中捕获的内容: 对于第一个字符,我使用[A-Za-z]表示的字符集。其次是\ w或空格0次或更多次。这被捕获到f1。

(?:\s*-\s*(?P<f1>[A-Za-z][\w\s]*))?$

我希望以下序列匹配并将值捕获到f1:

  • &#34; - 布鲁斯&#34; (F1 =布鲁斯)
  • &#34; - 布鲁斯迪金森&#34; (f1 =布鲁斯狄金森)

我希望以下内容不匹配:

  • &#34;布鲁斯&#34; (没有领先的破折号)
  • &#34; - 布鲁斯!&#34; (在名称之后和行尾之前有一个非单词(\ w)字符

我希望以下匹配但不会将值捕获到f1中(我希望它不匹配但是):

  • &#34; - 1Bruce&#34; (主角是数字)

这些是实际结果:

  • &#34; - 布鲁斯&#34; (f1 =布鲁斯)勾选;这工作
  • &#34; - 布鲁斯迪金森&#34; (f1 =布鲁斯迪金森)勾选;这工作

  • &#34;布鲁斯&#34; (f1 =未被捕获,但表达式是匹配的。这是错误的,因为Bruce与可选部分不匹配,接下来是$并不匹配Bruce)

  • &#34; - 布鲁斯!&#34; (f1 =不是cpatured,但表达式是匹配的;这是错误的,因为!,这意味着匹配不会出现在行尾。

我希望:

(?:\s*-\s*(?P<f1>[A-Za-z][\w\s]*))?

将消耗{ - Bruce},它应该离开!,因为下一个正则表达式令牌是$,它应该会失败;然而,电脑说不,所以我错了,但我不知道为什么:(

  • &#34; - 1Bruce&#34; (f1 =未捕获,但表达式匹配。这是可以理解的,因为整个{space dash space f1}序列是可选的,因为它不匹配,所以跳过该构造,然后没有其他任何东西可以处理输入;我们命中了一行)

如果我可以让这个工作,我可以让我的表达的其余部分以我想要的方式工作。我需要别人让我不同地思考这个问题。我花了2天没有正面输出,所以非常令人沮丧。

PS:我正在使用regex101.com来测试正则表达式。正则表达式将用作Rust应用程序的一部分,其正则表达式引擎基于谷歌的RE2。

最终,我需要能够识别由&amp;分隔的一系列名称,并且整个表达式是可选的?并且必须出现在$。

行的末尾

所以

  • { - 布鲁斯&amp;尼克和Dave Murray}有效

  • { - 布鲁斯&amp;尼克和戴夫穆雷&amp; }应该无效且不匹配

但一步一步!

1 个答案:

答案 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_]只匹配任何字母)。