有空格和无空格的正则表达式子组行为

时间:2019-07-09 10:12:56

标签: sql regex posix db2-400

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

我想理解为什么在下面的示例中必须包含空格:

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

结果

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

我希望,由于句点匹配任何字符(包括空格),因此两个正则表达式将具有相同的结果。

但是,即使接受了它们的拒绝,我也弄不清为什么第二组只捕获了最后三个。

谢谢。

1 个答案:

答案 0 :(得分:2)

这是贪婪的问题。

使用正则表达式

  

'((。*(\ d +))'

您明确要求数字前有一个空格,因此\ d +将获得3位数字。

使用正则表达式

  

'((。*(\ d +))'

点。*在匹配一个或多个数字之前将使用尽可能多的字符。因此。*将匹配“ MYPRODUCT 12”,\ d +将匹配“ 3”。

解决方案:非贪婪量词“?”。 正则表达式为

  

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

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

的其余位数匹配