0

我正在尝试REGEXP_REPLACE在 PL/SQL 中使用小写的相同文本替换一些文本。实际上,规则是我希望"()"只有一个字符之间的所有文本都是小写的。

这是一个例子:

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"内容放在小写字母中。

谢谢你的帮助。

此致。多发性硬化症

4

2 回答 2

0

(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) ;

如果你想要<>它周围的怪异:

 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}更准确替换)

于 2016-04-04T07:36:50.613 回答
0

糟糕的是,这必须是一个如此困难的问题!好像会很容易。

要处理可变数量的模式出现,您需要遍历字符串以查找它们。也许有人会想出一个巧妙的解决方案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;
于 2016-04-07T19:05:00.283 回答