【问题标题】:How can I replace multiple words "globally" using regexp_replace in Oracle?如何在 Oracle 中使用 regexp_replace 替换多个单词“全局”?
【发布时间】:2018-08-05 23:28:24
【问题描述】:

我需要将多个单词(例如 (dog|cat|bird))替换为字符串中可能有多个连续出现的单词。实际代码是从名称中删除称呼和后缀。不幸的是,我得到的垃圾数据有时包含“SNERD JR JR”。

我能够创建一个正则表达式模式来实现我的目标,但仅限于第一次出现。我实施了一个愚蠢的黑客来摆脱第二次出现,但我相信必须有更好的方法。我就是想不通。

这是我的“被黑”代码;

  FUNCTION REMOVE_SALUTATIONS(IN_STRING VARCHAR2) RETURN VARCHAR2 DETERMINISTIC
  AS
    REGEX_SALUTATIONS VARCHAR2(4000) := '(^|\s)(MR|MS|MISS|MRS|DR|MD|M D|SR|SIR|PHD|P H D|II|III|IV|JR)(\.?)(\s|$)';
  BEGIN
    RETURN TRIM(REGEXP_REPLACE(REGEXP_REPLACE(IN_STRING,REGEX_SALUTATIONS,' '),REGEX_SALUTATIONS,''));
  END REMOVE_SALUTATIONS;

我真的很自豪我能走到这一步,因为正则表达式对我来说不是很规则。感谢所有帮助。

编辑:

根据我的理解,regexp_replace 的默认值是进行全局替换。但是在外部机会我的数据库配置不同我确实尝试过;

select REGEXP_REPLACE('SNERD JR JR','(^|\s)(MR|MS|MISS|MRS|DR|MD|M D|SR|SIR|PHD|P H D|II|III|IV|JR)(\.?)(\s|$)',' ',1,0) from dual;

结果是;

SNERD JR

【问题讨论】:

  • 你的正则表达式占用太多:它需要第一个 JR demo 周围的两个空格。您能否检查一下前瞻是否在 oracle 中有效:demo with lookahead
  • 是的,我看到问题如您所说。据我所知,Oracle 不处理前瞻。我尝试了您的示例并对其进行了研究。该示例不起作用,并且我读到的内容说 Oracle 不会向前看。
  • 我尝试在没有前瞻的情况下这样做:(^|\b|\s)(MR|MS|MISS|MRS|DR|MD|M D|SR|SIR|PHD|P H D|II|III|IV|JR)(\.?)(\s|$),也许这会有所帮助Demo

标签: regex oracle11g


【解决方案1】:

使用REGEXP_REPLACE函数的occurrence参数。文档说:

occurrence是一个非负整数,表示发生了替换操作:

  • 如果您指定 0,则 Oracle 将替换所有匹配项。
  • 如果您指定一个正整数 n,那么 Oracle 将替换第 n 个出现

https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions137.htm#SQLRF06302

应该是这样的:

...
REGEXP_REPLACE(IN_STRING,REGEX_SALUTATIONS,' ', 1,0 )
...

【讨论】:

  • mrzasa,感谢您的帮助,我之前尝试过,并没有在我的帖子中提及。顺便说一句,第 4 个参数必须 > 0。请参阅上面我编辑的帖子。
  • 刚刚回答,见下方问题
  • mrzasa,在第 5 个参数中使用 0 不适用于我的数据库 (11g)。我在原始问题的“编辑”中发布了一个示例,您可以轻松测试。
  • 可以轻松测试我是否安装了 oracle 11g :)。由于我无法访问它,我可以根据文档和我的正则表达式知识为您提供建议。或者我可以停止这样做。
  • mrzasa 感谢您的帮助。不幸的是,即使你告诉我去哪里看,我也没有看到你关于向前看的帖子。我很抱歉。
猜你喜欢
  • 2020-01-21
  • 2016-08-31
  • 2021-10-05
  • 2020-02-01
  • 1970-01-01
  • 2021-03-22
  • 2018-08-14
  • 2015-12-07
  • 2021-11-01
相关资源
最近更新 更多