如何使捕获组在其之前/之后“吸收”空白而不捕获它?

时间:2014-02-06 05:42:34

标签: javascript regex

我找到了here的正则表达式。尝试下面的字符串,我面临的问题是,在第一个之后,每个捕获组的开头都有一个额外的空格。我需要空格匹配但我不需要它们捕获

正则表达式:

^(\/[a-zA-Z0-9]+)?(\s~[a-zA-Z]+)?([\w\s'()-]+)?((?:\s~[a-zA-Z]+){0,2})?$

在上面的链接中查看它使得理解起来更加简单。

这些是您可以逐个粘贴到测试字符串区域的一些字符串:

/test ~example matches ~extra ~space
this too has an extra ~space ~matched
/like wise for this
/and ~this

查看匹配组区域,注意在第一组之后,捕获组之间的前一个空格。

我想做的是:

对于第一个和第二个捕获组,我希望它们检测后续空间并吸收捕获它,以便第三个捕获组将不会检测并捕获额外的空间。对于第4个捕获组,我希望它检测前面的空格并吸收它但不捕获它。

吸收的意思是,在第三个捕获组不会意识到它存在的意义上,空间被“移除”。

我该怎么做?

感谢。

3 个答案:

答案 0 :(得分:1)

这是我提出的正则表达式 -

^(\/[a-zA-Z0-9]+)?(?:\s)?(~[a-zA-Z]+)?(?:\s)?([\w\'()\-\s]+)?(?:\s(~[a-zA-Z]+))?(?:\s(~[a-zA-Z]+))?$

根据要求将正则表达式分为两部分 -

  

对于第1和第2个捕获组,我希望它们能够检测到成功   空间并吸收它但不捕获它,以便第3个捕获组   不会检测并捕获额外的空间。

第1组和第2组的正则表达式 -

(\/[a-zA-Z0-9]+)?(\s~[a-zA-Z]+)?

所以,在每个第一和第二个捕获组之后,我添加了一个非捕获(?:\ s)?这使得第三个捕获组不会吸收前面的空间。这是我的正则表达式 -

(\/[a-zA-Z0-9]+)?(?:\s)?(~[a-zA-Z]+)?(?:\s)?
  

对于第4个捕获组,我希望它能够检测到前面的空间和   吸收它但不捕获它。

你的正则表达式

((?:\s~[a-zA-Z]+){0,2})?

这里,一个明显的解决方案是仅捕获文本部分([a-zA-Z])并且不捕获部分。 像这样的东西,

(?:(?:\s(~[a-zA-Z]+)){0,2})?
         ^^^^^^^^^^ Capturing only this.

但这是一个重复捕获组,实际上你在旧元素之上捕获一个新元素。基本上,重复捕获组将仅捕获最后一次迭代。 所以,如果你想匹配 -

" ~space ~matched",它只会捕获最后一个"~matched"

所以一个解决方案是,因为你要检查它是{0,2},你可以明确地检查它2次,就像这样 -

(?:\s(~[a-zA-Z]+))?(?:\s(~[a-zA-Z]+))?

但是如果{0,2}之后的要求发生了变化,那么最好的解决方案就是捕获前面的空格并分别用空格分割捕获的组。

->  OUTPUT - when I run this regex for the given strings in JavaScript-
["/test ~example matches ~extra ~space", "/test", "~example", "matches", "~extra", "~space", index: 0, input: "/test ~example matches ~extra ~space"] (index):18
["this too has an extra ~space ~matched", undefined, undefined, "this too has an extra", "~space", "~matched", index: 0, input: "this too has an extra ~space ~matched"] (index):18
["/like wise for this", "/like", undefined, "wise for this", undefined, undefined, index: 0, input: "/like wise for this"] (index):18
["/and ~this", "/and", "~this", undefined, undefined, undefined, index: 0, input: "/and ~this"] 

希望这会有所帮助。

答案 1 :(得分:0)

我认为这可以满足您的需求:

^(\/[a-zA-Z0-9]+)?(?:(\s~[a-zA-Z]+)\s)?([\w\s'()-]+)?(?:\s((?:~[a-zA-Z]+\s?){0,2}))?$

答案 2 :(得分:0)

试试这个正则表达式:

^(\/[a-zA-Z0-9]+)?\s?(~[a-zA-Z]+)?\s*([\w\s'()-]+)?\s?((?:~[a-zA-Z]+\s?){0,2})?$

在线演示:http://regex101.com/r/rA5tR0