匹配字符串的特定部分或匹配整个字符串

Matching specific parts of a string or else matching entire string

这里的想法是更好地对来自我们应用程序的日志消息进行分组。

想象一下正则表达式:

(^Case1|^Case2|Case3$)

和字符串:

预期的捕获结果将是

(最后一个没有)

因为我不想丢弃我没有明确定义的消息,如果字符串不匹配正则表达式中定义的任何情况,我想捕获整个字符串。

出于天真,我将代码更改为:

(^Case1|^Case2|Case3$|.*)

然而,最后一个捕获组现在似乎覆盖了其他组所做的捕获,并且始终是被评估的那个……所以我总是匹配整个字符串……除非要匹配的文本在字符串的开头。

例如 使用:

(^Case1|^Case2|Case3$|.*)

给予

但使用

(^Case1|^Case2|Case3$|.*)

给予

希望有人赐教!

提前致谢。

已编辑注释 - 需要注意的事项..

正则表达式从左到右交替处理。
但是,是在当前字符位置处理
例如,在此表达式 (here$)|.* 中,首先在
处检查 here$ 字符位置0,主题字符串为'first here',其中'f' 首先根据 here$ 中的 'h' 检查。不匹配..

所以,它进入下一个交替表达式.*,它可以匹配'f'
并匹配到字符串的末尾。

即使主题字符串末尾包含“...此处”,它也不会匹配
在这种情况下。

但是,如果您有此正则表达式 .*(here$)|.*,第一个 .*(here$) 将匹配,因为
'f' 可以一直匹配到最后的 'here'。


从技术上讲,您想知道匹配的是哪种情况,同时
匹配所有其他文本。

如果可以,方法有很多,这里介绍两种。

这使用分支重置。

 # ^(?|(Case[12]).*|.*(Case3)|(.+))$

 ^ 
 (?|
      ( Case [12] )                 # (1)
      .* 
   |  
      .* 
      ( Case3 )                     # (1)
   |  
      ( .+ )                        # (1)
 )
 $ 

这使用单独的捕获组来具体告诉您哪种情况
匹配。

 # ^(?:(Case[12]).*|.*(Case3)|(.+))$

 ^ 
 (?:
      ( Case [12] )                 # (1)
      .* 
   |  
      .* 
      ( Case3 )                     # (2)
   |  
      ( .+ )                        # (3)
 )
 $