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" 内容小写。

感谢您的帮助。

最好的问候。 女士

【问题讨论】:

也许您可以重新阅读您的问题,因为 ( ) 字符和 &lt; &gt; 之间存在一些混淆。 代替大写锁定和粗体文本使用代码块,它更能被社区和全人类接受 【参考方案1】:

(with Oracle11g) 下面是如何替换第一个匹配项:

使用REGEXP_instrREGEXP_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) ;

如果你想要奇怪的&lt;&gt;

 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 替换所有数字

Orcal中文本替换

Oracle 正则表达式函数-REGEXP_REPLACE 使用例子

使用 oracle regexp_replace 替换代码的某些部分

如何在 edb 中使用相同的 REGEXP_REPLACE(Oracle sql)