正则表达式组包含if条件


Regex group include if condition

我尝试使用这个正则表达式/^('S+)(?:'?$|$)/

yoloyolo?

适用于这两个字符串,但在第二个字符串(yolo?)上,?将包括在捕获组('S+)上。

这是一个bug的正则表达式或我已经犯了一些错误?

编辑:我不想要那个'?'包括在捕获组中。对不起,我英语不好。

您可以使用

  • 如果您想要捕获的内容不能包含?,请使用否定的字符类[^...](参见这里的演示):

    ^([^'s?]+)'??$
    
  • 如果你想捕获的可以有?在它(例如,yolo?yolo?和你想yolo?yolo),您需要通过添加?来使量词+变为惰性(参见这里的演示):

    ^('S+?)'??$
    
  • 顺便说一句,这里不需要捕获组,您可以使用提前查看(?=...)并查看整个匹配(参见这里的演示):

    ^[^'s?]+(?='??$)
    

发生了什么

规则是:量词(如+)默认是贪婪的,regex引擎将返回它找到的第一个匹配。

考虑这里的含义:

  • 'S+将首先匹配yolo?中的一切,然后引擎将尝试匹配(?:'?$|$)
  • '?$失败(我们已经在字符串的末尾,所以我们现在尝试匹配一个空字符串,没有?),但是$匹配。

正则表达式已经成功地到达了它的终点,引擎返回匹配,其中'S+匹配了所有字符串,并且所有内容都在第一个捕获组中。

要匹配你想要的,你必须使量词懒惰(+?),或防止字符类(是的,'S是一个字符类)从匹配你的结束分隔符?(与[^'s?]为例)。

这是正确的响应,因为'S+贪婪地匹配一个或多个非空白字符,其中?是一个。

因此,问号在('S+)组中匹配,而非捕获组解析为$,您可以通过使用

将匹配设置为非贪婪,使其按预期工作:
/^('S+?)(?:'?$|$)/

演示

或者您可以限制字符组:

/^([^'s?]+)(?:'?$|$)/
演示

设置+不贪心:

^('S+?)'??$

下面的正则表达式将捕获后跟选项?的所有非空格字符,

^(['S]+)'??$

演示

^(['w]+)'??$

演示

如果您使用'S+,它甚至也匹配?字符。因此,要分隔单词和非单词字符,可以使用上面的正则表达式。它将只捕获单词字符并匹配后跟一个或多个单词字符的可选?

这样做是因为'S匹配任何非空白字符并且它正在贪婪

对于非贪婪的匹配,?紧接+量词将防止这种情况发生。

^('S+?)'??$

或者在这里使用'w,它匹配任何单词字符。

^('w+)'??$