有和没有 space 的正则表达式子组行为

Regex sub-group behaviour with and without space

假设任务是将产品代码中的最后一个数字附加到自身,并在原始数字和添加的数字之间添加连字符(纯粹用于实验)。

我想了解为什么在以下示例中必须包含 space:

with foo ( prod )                         
as ( values ('MYPRODUCT 123'))            
select                                    
 'dot aster space' as test_type,          
 '''(.* (\d+))'',''-''' as the_regex, 
 regexp_replace(prod,'(.* (\d+))','-')
from foo                                  
 UNION ALL                                
select                                    
 'dot aster no space',                    
 '''(.*(\d+))'',''-''',               
 regexp_replace(prod,'(.*(\d+))','-') 
from foo                                  

结果

TEST_TYPE           THE_REGEX             REGEXP_REPLACE   
dot aster space     '(.* (\d+))','-'  MYPRODUCT 123-123
dot aster no space  '(.*(\d+))','-'   MYPRODUCT 123-3  

我原以为,由于句点匹配任何字符,包括空格 space,所以两个正则表达式会产生相同的结果。

然而,即使承认他们没有,我也无法弄清楚为什么第二组中只捕获了最后 3 个。

谢谢。

贪心的问题

使用正则表达式

'(.* (\d+))'

你在数字前明确要求 space,所以 \d+ 将得到 3 位数字。

使用正则表达式

'(.*(\d+))'

点 .* 在匹配一个或更多数字之前会使用尽可能多的字符。所以 .* 将匹配 'MYPRODUCT 12' 而 \d+ 将匹配 '3'.

解决方案:non-greedy 量词“?”。 正则表达式为

'(.*?(\d+))'

它将匹配 \d+ 的最大位数,然后是 .*

的余数