REGEXP_REPLACE 用相同的小写文本替换文本
Posted
技术标签:
【中文标题】REGEXP_REPLACE 用相同的小写文本替换文本【英文标题】:REGEXP_REPLACE replacing text with the same text in lower case 【发布时间】:2016-07-22 07:09:04 【问题描述】:我正在尝试在 PL/SQL 中使用 REGEXP_REPLACE
将某些文本替换为相同的小写文本。实际上,规则是我希望 "()"
之间只有一个字符的所有文本都为小写。
这是一个例子:
SELECT REGEXP_REPLACE(
'i want what what is between <> in lower case : I am a test(E) (A) (HELLO)'
, '(\(\D\))', '<\1>'
) FROM DUAL
结果:
I want what is between <> in lower case : I am a test(e) (a) (HELLO)
或者这是因为我对我的锻炼有点困惑:
I want what is between <> in lower case : I am a test<(e)> <(a)> (HELLO)
我怎样才能得到我的小写文本?我尝试了几种方法,但我无法摆脱它。我不知道要告诉REGEXP_REPLACE
将"\1"
内容小写。
感谢您的帮助。
最好的问候。 女士
【问题讨论】:
也许您可以重新阅读您的问题,因为(
)
字符和 <
>
之间存在一些混淆。
代替大写锁定和粗体文本使用代码块,它更能被社区和全人类接受
【参考方案1】:
(with Oracle11g
) 下面是如何替换第一个匹配项:
使用REGEXP_instr
和REGEXP_substr
能够将lower
应用于匹配的模式
SELECT substr(it, 1 , REGEXP_instr( it, '(\(\D\))')-1)
||lower( REGEXP_substr(it, '(\(\D\))') )
||substr(it, REGEXP_instr( it, '(\(\D\))')+3, length(it))
FROM (SELECT 'i want what what is between <> in lower case : I am a test(E) (A) (HELLO)' it from dual) ;
如果你想要奇怪的<>
:
SELECT substr(it, 1 , REGEXP_instr( it, '(\(\D\))')-1)
|| '<'
||lower( REGEXP_substr(it, '(\(\D\))') )
|| '>'
||substr(it, REGEXP_instr( it, '(\(\D\))')+3, length(it))
FROM (SELECT 'i want what what is between <> in lower case : I am a test(E) (A) (HELLO)' it from dual) ;
我认为您不能在 Oracle 中使用递归正则表达式。因此,如果您希望能够替换 2 次出现:
SELECT substr(rit, 1 , REGEXP_instr( rit, '(\([[:upper:]]1\))')-1)
||lower( REGEXP_substr(rit, '(\([[:upper:]]1\))') )
||substr(rit, REGEXP_instr( rit, '(\([[:upper:]]1\))')+3, length(rit))
from (
(SELECT substr(it, 1 , REGEXP_instr( it, '(\([[:upper:]]1\))')-1)
||lower( REGEXP_substr(it, '(\([[:upper:]]1\))') )
||substr(it, REGEXP_instr( it, '(\([[:upper:]]1\))')+3, length(it)) rit
FROM (SELECT 'i want what what is between <> in lower case : I am a test(E) (A) (HELLO)' it from dual))
) ;
(+ 我将\D
替换为[[:upper:]]1
,这样更准确)
【讨论】:
【参考方案2】:糟糕的是,这一定是一个如此困难的问题!似乎很容易。
要处理可变数量的模式出现,您需要遍历字符串以查找它们。也许有人会想出一个使用CONNECT BY
或其他东西的巧妙解决方案,但与此同时,既然您使用的是 PL/SQL,为什么不去老派并创建一个功能呢?可以说它更容易维护,并且将被包装在一个可供所有人使用的可重复使用的单元中。传递一个字符串并让它返回清理后的版本。
SQL> select lower_single_letters('I want what is between in lower case : I am a test(E) (A) (HELLO)') text
from dual;
TEXT
--------------------------------------------------------------------------------
I want what is between in lower case : I am a test(e) (a) (HELLO)
SQL>
这里有一些示例代码,因为我想要一个在我的实用程序包中使用的示例:
CREATE OR REPLACE function lower_single_letters(string_in varchar2) return varchar2 is
tmp_string varchar2(1000) := string_in; -- Holds the string
regex_pattern constant varchar2(20) := '\([[:upper:]]\)'; -- Pattern to look for '(A)'
letter_offset integer; -- Offset of the pattern
letter varchar2(1); -- The letter to lower()
BEGIN
-- Loop while the pattern is found in the string passed in
while regexp_like(tmp_string, regex_pattern)
loop
-- Get the offset in the string
letter_offset := regexp_instr(tmp_string, regex_pattern)+1;
-- Get the letter
letter := substr(tmp_string, letter_offset, 1);
-- Replace it in the string
tmp_string := regexp_replace(tmp_string, '.', lower(letter), 1, letter_offset);
end loop;
-- Return it when the pattern is no longer found
return(tmp_string);
END lower_single_letters;
【讨论】:
以上是关于REGEXP_REPLACE 用相同的小写文本替换文本的主要内容,如果未能解决你的问题,请参考以下文章
Regexp_Replace 在 Oracle 中多次出现具有相同替换次数的字符
Postgresql regexp_replace 替换所有数字
Oracle 正则表达式函数-REGEXP_REPLACE 使用例子