为什么这个正则表达式不接受" s 1"输入类型?

时间:2014-10-16 20:37:36

标签: c++ regex

我有正式的正则表达式: /([^\s*][\l\u\w\d\s]+) (\d)/ 它应该匹配形式的字符串:" some-string digit&#34 ;,例如" stackoverflow 1"。 这些字符串在开头不能有空格

效果很好,除了开头有一个字符的简单字符串,例如:" s 1"。我该如何解决?我在boost :: regex(PCRE兼容)中使用它。

3 个答案:

答案 0 :(得分:1)

[^\s*]占用了你的第一个字符串字符,所以当你需要一个或多个字符串字符后,它就会失败:

/([^\s*][\l\u\w\d\s]+) (\d)/
   ^^^^  ^^^^^^^^^^     ^^
    "s"   no match      "1"

如果您修正了错误的*

/([^\s]*[\l\u\w\d\s]+) (\d)/
   ^^^   ^^^^^^^^^^     ^^
   "s";      "s"        "1"
  match
then cancelled
by backtracking

但是为了避免回溯,我会像这样编写正则表达式:

/([\l\u\w\d]+[\l\u\w\d\s]*) (\d)/

请注意,我只显示正则表达式本身 - 根据需要重新应用额外的反斜杠以用于C ++字符串文字; e.g。

const std::string my_regex = "/([\\l\\u\\w\\d]+[\\l\\u\\w\\d\\s]*) (\\d)/";

无论如何,这可能会更加优化(我确定大多数这些角色类都是多余的),但这应该可以解决您的问题。

您可以测试正则表达式here

答案 1 :(得分:1)

问题是你的*位置错误:[^\s*]只匹配一个既不是空白也不是星号的字符。 (s中的"s 1"有资格“既不是空白也不是星号”,因此它会被匹配和使用,并且不再可用作下一部分[\l\u\w\d\s]+的匹配项。请注意,带有两个空格的"s 1"会成功。)

你可能意味着[^\s]*,它匹配任何数字(包括零)的空白字符。如果你做了那么小的修改,那就会修正你的正则表达式。

但是,还有其他改进。首先,字母类缩写的反斜杠+字母序列可以通过大写字母来否定:字符类“不在\s中的所有内容可以按上述方式编写,{ {1}},但它也可以更简单地编写为[^\s]

接下来,我不知道\S\l是什么。您已标记此\u,因此您可能正在使用标准c++库,该库使用ECMAScript正则表达式语法。但是ECMAScript正则表达式规范没有定义那些元字符。

如果您要匹配“小写字母”和“大写字母”,那么这些字母为regex[:lower:] - 但这两组字母已包含在[:upper:]中,因此您不需要将它们包含在也具有\w的字符类中。

拉出这些字符会留下\w的字符类 - 这仍然是多余的,因为[\w\d\s]也包含数字,所以我们不需要\w。删除它,我们有\d,它匹配“下划线,字母,数字,空格,制表符,换页符或换行符(换行符)。”

这使整个正则表达式[\w\s]:零个或多个非空白字符,后跟至少一个空格或单词字符,后跟一个空格,后跟一个数字。这对我来说似乎是一套不同寻常的标准,但它绝对应该与“1”相匹配。在我的测试中确实如此。

答案 2 :(得分:-1)

我希望你能做到这样的事情:

添加     {X,},其中X是数字,在第二组括号

如下所示

([^\\s*][\\l\\u\\w\\d\\s]{2,}) (\d)

将2替换为您想要的最小字符串长度。