【问题标题】:How to make capture group "absorb" whitespace before/after it without capturing it?如何使捕获组“吸收”它之前/之后的空白而不捕获它?
【发布时间】:2014-02-06 05:42:33
【问题描述】:

我找到了一个正则表达式 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

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

我想做的是这样的:

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

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

我该怎么做?

谢谢。

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

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

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

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

    对于第一个和第二个捕获组,我希望他们检测到一个成功的 空间并吸收但不捕获它,以便第三个捕获组 不会检测和捕获额外的空间。

    第一组和第二组的正则表达式 -

    (\/[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 部分。 像这样的,

    (?:(?:\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"] 
    

    希望这会有所帮助。

    【讨论】:

    • 仅供参考,(?:\s)? 中的小组没有做任何有用的事情。 \s? 就是你所需要的。
    • 这太棒了,到目前为止,一切都做得非常好。我可能会改变一些东西,但总的来说,这正是我想要的。也非常感谢您的解释!哦,在第三次捕获的正则表达式中,由于您重新排序了一些字符,因此您需要使用 \ 转义它们,尤其是破折号。
    【解决方案2】:

    我认为这是你想要的:

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

    【讨论】:

      【解决方案3】:

      试试这个正则表达式:

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

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

      【讨论】:

        猜你喜欢
        • 2017-05-05
        • 1970-01-01
        • 1970-01-01
        • 2017-06-20
        • 2021-07-08
        • 1970-01-01
        • 2011-02-01
        • 2012-04-22
        • 2015-06-25
        相关资源
        最近更新 更多