我想将全名的每个首字母大写,但有一个例外:介词应该小写。
介词有:[“da”、“de”、“di”、“do”、“du”、“das”、“des”、“dis”、“dos”、“dus”]。
到目前为止我有这段代码,但它很糟糕而且不完整。如果我这样做(把我需要的所有例外),这将是巨大的。
DBMS_OUTPUT.PUT_LINE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE
(INITCAP ('ronald DAS silva'), '(D|d)a', 'da'),
'(D|d)o', 'do'), '(D|d)e', 'de'),'(D|d)o', 'do'),'(D|d)u', 'du'));
我已经尝试在函数内部使用REGEXP_REPLACE
(使用此正则表达式 -> ^(d|D)[a-zA-Z]{1,2}$
)INITCAP
,但没有成功。
那么,有没有办法让它更容易呢?
编辑:
我现在有这个:
DBMS_OUTPUT.PUT_LINE(REGEXP_REPLACE(INITCAP('ronald DAS silva'), '([d|D][[:alpha:]]{1,2})', LOWER('\1')));
它几乎可以工作,但是由于LOWER
某种原因该功能没有做他的工作,为什么?如果我把 LOWER('A') 它工作。
编辑 2 - 附加测试:
每个以字母“d”开头的名称都将转换为小写,并且不应该发生这种情况。
然后有一些情况:
- 丹尼尔
- 神威
- 迪杰斯特拉
- 唐纳德
- 多苓
完整代码
DECLARE
TYPE t_name IS VARRAY(3) OF VARCHAR2(100);
v_names t_name := t_name(' Donald dIs siLvA',
'daniEl da sIlvA XaVIeR ',
' DeYse De Olivier dA loPeS');
BEGIN
DBMS_OUTPUT.PUT_LINE(RPAD('Name w/o format', 60, ' ') ||
'Name formatted');
DBMS_OUTPUT.PUT_LINE(RPAD('---------------------', 60, ' ') ||
'---------------------');
FOR i IN 1..v_names.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(RPAD(v_names(i), 60, ' ') ||
f_format(v_names(i)));
END LOOP;
END;
FUNCTION f_format(p_str VARCHAR2)
RETURN VARCHAR2
AS
BEGIN
RETURN REGEXP_REPLACE(
REGEXP_REPLACE(
INITCAP(p_str),
'((D)([aeiou](s|$)?))', 'd\3'),
'[[:space:]]+', ' ');
END;