【问题标题】:Regex101 vs Oracle RegexRegex101 与 Oracle 正则表达式
【发布时间】:2017-12-31 08:16:08
【问题描述】:

我的正则表达式:

^\+?(-?)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...)

我错过了什么?

编辑

它像正则表达式末尾的贪婪量词*,而不是懒惰的*?,但我肯定设置了懒惰的。

【问题讨论】:

  • 你怎么知道哪个0是数字的一部分?你如何代表 9,000 人?
  • @WiktorStribiżew 来源?
  • @user7294900 这很容易。有一个惰性量词会从拖尾 0 中捕获至少一个零
  • 我正在检查文档,但我怀疑正则表达式引擎是基于 Henry Spencer 的正则表达式库的。这意味着原因要深得多,因为它支持惰性量词。解决方法很简单。
  • @WiktorStribiżew 如果您将解决方案发布为答案,我将不胜感激

标签: regex oracle


【解决方案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]+?))贪心类型由第一个 +? 设置(即懒惰)。

【讨论】:

  • 差不多。当, 之后我们只有 0 时它不起作用,例如:+000099,0000000
  • @ilovkatie 我认为你的也不是。您在问题中讨论了不同的问题。 +000099,0000000 的预期结果是什么?还有哪些其他测试用例?
  • regex101.com/r/erFPtk/3 它正在工作。输出应为99,0。但正如您的回答所指出的,它不适用于 oracle。
  • 好的,惰性量词可以在第 1 组中使用,这将起作用 - '^\+?(-?)0*([0-9]+?,[0-9]+?)0*$' - rextester.com/SQZP50172,请参阅问题更新。我提到了行为是不一致的,但并不是不可能混淆量词类型。
  • 检查我更新的说明。我想现在应该都清楚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 2021-05-22
  • 2017-05-13
  • 1970-01-01
相关资源
最近更新 更多