【发布时间】: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
【问题讨论】:
-
你的正则表达式占用太多:它需要第一个
JRdemo 周围的两个空格。您能否检查一下前瞻是否在 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