LPAD和REGEXP_替换交互变得不可靠?
这里有一些我无法解释的东西,希望能得到一些帮助,看看我明显遗漏了什么:) 在制定此问题的解决方案时: 我认为一个聪明的regexp_replace+LPAD会产生更好的排序值。然而,由于某种原因,LPAD一直表现不好。以下是简化测试中的“问题”:LPAD和REGEXP_替换交互变得不可靠?,regex,oracle,Regex,Oracle,这里有一些我无法解释的东西,希望能得到一些帮助,看看我明显遗漏了什么:) 在制定此问题的解决方案时: 我认为一个聪明的regexp_replace+LPAD会产生更好的排序值。然而,由于某种原因,LPAD一直表现不好。以下是简化测试中的“问题”: with w_data as ( select '9' v from dual union all select '18' v from dual ) select v, lpad(v,
with w_data as (
select '9' v from dual union all
select '18' v from dual
)
select v,
lpad(v, 4, '0' ) a,
regexp_replace(v, '([0-9]*)', lpad('\1', 4, '0')) b
from w_data
/
V
--
A
----
B
----------
9
0009
00900
18
0018
001800
2 rows selected.
如您所见,列“a”的行为与预期一致。。长度为4的字符串,左侧填充0
但是,一旦它通过regexp\u替换。。。它开始变得奇怪。。。为什么会这样?
如何将其与regexp\u replace“正确”结合使用?
(请注意,我的正则表达式和字符串(根据链接的问题)稍微复杂一些;)
[编辑]
使用“[0-9]+”尝试。。但是仍然没有正确填充
with w_data as (
select '9' v from dual union all
select '18' v from dual
)
select v,
lpad(v, 4, '0' ) a,
regexp_replace(v, '([0-9]+)', lpad('\1', 4, '0')) b
from w_data
/
V
--
A
----
B
----------
9
0009
009
18
0018
0018
2 rows selected.
请注意,18正确显示(“0018”),但9仅显示为“009”3个字符?应该是四个:“0009”…LPAD不理解正则表达式替换的特殊语法;这仅在直接传递给REGEXP函数时才有意义。所以这个表达式:
lpad('\1', 4, '0')
只是返回字符串“00\1”。然后将该字符串传递给REGEXP_REPLACE,它在正则表达式上下文中解释“\1”。如果您确定所有数字都不超过4位,则可以使用以下方法:
with w_data as (
select '9' v from dual union all
select '18' v from dual
)
select v,
REGEXP_REPLACE(
REGEXP_REPLACE(v, '([0-9]+)', '000\1'),
'(0*)([0-9]{4})',
'\2') b
from w_data
如果不是,这里有一个更复杂的解决方案:
with w_data as (
select '9' v from dual union all
select '18' v from dual union all
select '123456' v from dual
)
select v,
REGEXP_REPLACE(
REGEXP_REPLACE(v, '([0-9]+)', '000\1'),
'(0*)([1-9]?[0-9]{4})',
'\2') b
from w_data
我不明白你想要什么,你能把样品的格式改好吗。即使是OK,请参考另一个问题,您也应该始终在此处发布所有相关代码。你永远不知道是否有人删除了另一个问题请注意,
[0-9]*
可以在每个不匹配的序列/符号之前匹配一个空位置,我认为你需要[0-9]+
。对不起。。意味着列“a”的行为正常。。。需要4个字符串的结果…@Stribizev:+更好。。但还是不完全。。让我更新它不可能在regexp\u replace的替换模式中传递反向引用。你需要找到另一种方法。啊。。。好吧,这是有道理的。。。O.O所以最好的“解决方法”可能是:lpad(regexp\u replace(v),([0-9]+),'\1'),4,'0')
?我认为,regexp\u replace调用是无操作的。正则表达式的每个匹配项都将替换为自身。您是否试图从输入字符串中删除非数字字符?最终(根据另一个问题的链接),我尝试将9和18的字符串版本排序为“更好”,将它们转换为“0009”和“0018”。。正则表达式之所以出现,是因为它使用的是版本(如1.9、1.18等)因此,我试图将1.9转换为“0001.0009”(例如)。。。然后它会对“0001.0018”进行更好的排序。(我甚至知道正则表达式会给我带来麻烦:)所以我一直在寻找像这样的任务来学习/练习:)这太棒了。只是用同样的方法为MySQL/MariaDB创建了一个函数。太好了!我只需要写\\1
而不是\1
。我的数据库版本:10.2.21-MariaDB-1:10.2.21+maria~bionic