我有FUNCTION
用STRING
替换多个(连续)水平空间,并带有奇异的水平空间;
e.g。
STR_ORIG = 'Hello World'
STR_NEW = 'Hello World'
功能如下;
CREATE OR REPLACE FUNCTION CP_RDN_PUNCT(
INS VARCHAR2)
RETURN VARCHAR2
AS
OUTSTR VARCHAR2(4000);
STR VARCHAR2(4000);
BEGIN
STR := INS;
WHILE (INSTR(STR,' ',1) > 0 )
LOOP
OUTSTR := OUTSTR || ' ' || SUBSTR(STR,1,INSTR(STR,' ',1) - 1);
STR := TRIM(BOTH ' ' FROM SUBSTR(STR,INSTR(STR,' ',1)));
END LOOP;
OUTSTR := OUTSTR || ' ' || TRIM(STR);
RETURN TRIM(OUTSTR);
END CP_RDN_PUNCT;
但是,我想扩展这个FUNCTION
,以便它能够纠正基本的标点符号格式(逗号,句号和括号)。但是,重要的是FUNCTION继续删除多个(连续的)水平空间。
例如;
如果STR_ORIG = 'Hello , Marc'
输出将变为'Hello, Marc'
如果STR_ORIG = 'Hello.Marc'
输出将变为'Hello. Marc'
如果STR_ORIG = 'Hello(Marc )'
输出将变为'Hello (Marc)'
我想要使用的规则是相当基本的:
Comma;...............One HORIZONTAL SPACE after a Comma.
No HORIZONTAL SPACE before a Comma.
Full Stop;...........One HORIZONTAL SPACE after a Full Stop.
No HORIZONTAL SPACE before a Full Stop.
Open Parenthesis;....No HORIZONTAL SPACE after an Open Parenthesis.
One HORIZONTAL SPACE before an Open Parenthesis.
Closed Parenthesis;..One HORIZONTAL SPACE after an Closed Parenthesis*.
No HORIZONTAL SPACE before an Closed Parenthesis.
*注意:当在闭括号后直接出现逗号或句号时,而不是“{1}}'规则它将使用'否HORIZONTAL SPACE
'规则。
我认为HORIZONTAL SPACE
是解决此问题的最佳方法(我已经探索过使用纯SQL(FUNCTION
)但代码开始变得非常混乱 - 主要是由于数据不一致)。此外,如果我希望将来添加其他规则(例如下划线规则),我假设REG_EXP
更容易维护。但是,我一如既往地接受专业人士的建议。
非常感谢提前。
答案 0 :(得分:1)
您可以使用REGEXP
编写函数,而不是使用INSTR
,SUBSTR
。
注意:此功能不考虑出现在同一字符串中的多种模式。所以如果","并且"。"两者都表明它不会起作用。因此,您可以自己编写所需的所有转换代码,EXCEPTION
处理等以涵盖此类方案。我已经告诉你如何做到这一点。您可能必须使用IF THEN
或CASE
块重写,因为我在with
子句中编码了类似PL / SQL的代码。
CREATE OR REPLACE FUNCTION CP_RDN_PUNCT(
inp_pattern VARCHAR2)
RETURN VARCHAR2
AS
outstr VARCHAR2(4000);
BEGIN
with reg ( pattern, regex ,replacement ) AS
(
select ',' , ' *, *', ', ' FROM DUAL UNION ALL
select '.' , ' *\. *', '. ' FROM DUAL UNION ALL
select '(' , ' *\( *', ' (' FROM DUAL
)
SELECT
TRIM(regexp_replace(rep,' *\) *',') ') ) INTO outstr
FROM
(
SELECT
regexp_replace(inp_pattern,regex,replacement) rep
FROM
reg
WHERE
inp_pattern LIKE '%'
|| pattern
|| '%'
);
RETURN outstr;
END;
/
答案 1 :(得分:1)
我能想到的另一种方法是使用associated array
来存储模式和替换而不是普通的sql。然后在循环中对字符串应用每个转换。
CREATE OR REPLACE FUNCTION cp_rdn_punct2 (
inp_pattern VARCHAR2
) RETURN VARCHAR2 AS
v_outstr VARCHAR2(1000) := inp_pattern;
TYPE v_astype IS
TABLE OF VARCHAR2(40) INDEX BY VARCHAR(40);
v_pat v_astype;
v_idx VARCHAR2(40);
BEGIN
v_pat(' *, *' ) := ', ';
v_pat(' *\. *') := '. ';
v_pat(' *\( *') := ' (';
v_pat(' *\) *') := ') ';
v_idx := v_pat.first;
WHILE v_idx IS NOT NULL LOOP
v_outstr := regexp_replace(v_outstr,v_idx,v_pat(v_idx) );
v_idx := v_pat.next(v_idx);
END LOOP;
RETURN v_outstr;
END;
/