【问题标题】:REGEXP_REPLACE - remove commas from string ONLY if enclosed in ()'sREGEXP_REPLACE - 仅当包含在 () 中时才从字符串中删除逗号
【发布时间】:2011-10-13 04:43:11
【问题描述】:

我在 oracle 论坛网站上找到了一个示例:

输入字符串:a, b, c (x, y, z), a, (xx, yy, zz), x,

WITH t AS (SELECT 'a, b, c (x, y, z), a, (xx, yy, zz), x,' col1 
         FROM dual)
SELECT t.col1
 , REGEXP_REPLACE(t.col1, '(\(.*?\))|,', '\1') new_col
FROM t

输出:a b c (x, y, z) a (xx, yy, zz) x

但我想反其道而行之。只需从() 内部删除此字符, 并留在外部。

输出:a, b, c (x y z), a, (xx yy zz), x,

【问题讨论】:

  • 您希望() 之间有多少个,
  • REGEXP_REPLACE 在 Oracle 中使用没有环视功能的风味 POSIX ERE。此信息取自here
  • 添加到@bw_üezi 的评论 - 我已经确认 Oracle 不支持使用 REGEXP_REPLACE 的外观。 强制注释:它看起来不像数据库中应该是原始的数据 - 特别是如果您要查询它。你确定你不能正常化它吗? (我知道你现在可能不能......)

标签: sql regex oracle character


【解决方案1】:

这将适用于括号中的恒定长度参数。

REGEXP_REPLACE(t.col1, '(\(.*?),(.*?),(.*?\))', '\1\2\3') new_col

受@Kobi 评论启发的更新:
此正则表达式删除() 之间的第一个、可选的第二个和可选的第三个,
它可以扩展到 9(我有一个 book 声明 \1 ... \500 应该是可能的,但只有 \1 ... \9 有效)

REGEXP_REPLACE(t.col1, '\(([^,]*),([^,]*),?([^,]*),?([^,]*)\)', '(\1\2\3\4)') new_col

【讨论】:

  • 您可以使用\(([^,]*?),([^,)]*?),?([^,)]*?)\)(\1\2\3) 之类的东西来支持2 或3 个元素,并且可以轻松地将其扩展为合理的最大元素数。在这种情况下,找到一个通用的正则表达式很棘手......
  • 多少,你期望在 () 之间?无限 :)) 因此,这个正则表达式必须更通用
  • @hamdi 您可以扩展此处显示的此正则表达式以在括号之间使用 4 个元素运行,以支持最多 9 个元素。处理无限数量的元素 SQL 可能不是正确的工具。更通用的正则表达式可以通过 Oracle 不支持的“环视”功能实现。
【解决方案2】:

不确定 REGEXP_REPLACE 是否支持负前瞻和后瞻,但如果支持,这将起作用:,(?<!\)[^\(]*)(?![^\)]*\()

我用 C# 测试过:

string s = "a, b, c (x, y, z), a, (xx, yy, zz), x,";

Console.WriteLine(Regex.Replace(s, @",(?<!\)[^\(]*)(?![^\)]*\()", ""));

【讨论】:

  • REGEXP_REPLACE 在 Oracle 中使用没有环视功能的风味 POSIX ERE。此信息取自here
【解决方案3】:

您使用的正则表达式稍作修改:

REGEXP_REPLACE(column_name, '((\)|^).*?(\(|$))|,', '\1')

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多