我的正则表达式:
^\+?(-?)0*([[:digit:]]+,[[:digit:]]+?)0*$
正在删除以十进制数表示的前导+和前导以及尾随0。
我已在regex101
中对其进行了测试对于输入:+000099,8420000
和替换\1\2
,它会返回99,842
我想在Oracle数据库11g中获得相同的结果:
select REGEXP_REPLACE('+000099,8420000','^\+?(-?)0*([[:digit:]]+,[[:digit:]]+?)0*$','\1\2') from dual;
但是它返回99,8420000
(拖尾0仍然存在......)
我失踪了什么?
修改
它在正则表达式结束时就像贪婪的量词*
,而不是懒惰的*?
,但我肯定会设置懒惰的。{/ p>
答案 0 :(得分:1)
对于所有使用Henry Spencer的正则表达式库实现的人来说,这个问题是众所周知的:懒惰的量词不应该与同一个分支中的贪婪量词混淆导致未定义的行为。 R中使用的TRE正则表达式引擎显示相同的行为。虽然你可以在某种程度上混合懒惰和贪婪的量词,但你必须始终确保得到一致的结果。
解决方案是仅在捕获组中使用延迟量词:
select REGEXP_REPLACE('+000099,8420000', '^\+?(-?)0*([0-9]+?,[0-9]+?)0*$','\1\2') as Result from dual
请参阅online demo
[0-9]+?,[0-9]+?
部分匹配1位或更多位数,但尽可能少,然后使用逗号,然后是1位或更多位数,尽可能少。
更多测试(select REGEXP_REPLACE('+00009,010020','[0-9]+,[0-9]+?([1-9])','\1') from dual
产生+20
)证明 组中的第一个量词设置了量词贪婪类型。在上面的例子中,第0组量词贪婪被第一个?
量词设置为 greedy ,而第1组(即([0-9]+?,[0-9]+?)
)贪婪类型设置为第一个{{ 1}}(这是懒惰的)。