我需要在句子或字符串中反转单词的位置。
For example : "Hello World! I Love StackOverflow", to be displayed as "StackOverflow Love I World! Hello".
可以使用SQL
完成吗?字长不大于VARCHAR2(4000)
,这是Oracle VARCHAR2
表格列中的最大长度支持。
我得到了用于反转字符串的解决方案(仅按相反顺序的字符)
答案 0 :(得分:9)
基于XML的版本,以避免定义自己的功能; listagg()
需要11g:
select listagg(word, ' ') within group (order by rn desc) as reversed
from (
select word, rownum as rn
from xmltable('for $i in ora:tokenize($STR, " ") return $i'
passing 'Hello World! I Love StackOverflow' as str
columns word varchar2(4000) path '.'
)
);
REVERSED
----------------------------------------
StackOverflow Love I World! Hello
XMLTable()
执行令牌化,并指定行号:
select rownum as rn, word
from xmltable('for $i in ora:tokenize($STR, " ") return $i'
passing 'Hello World! I Love StackOverflow' as str
columns word varchar2(4000) path '.'
);
RN WORD
---------- --------------------
1 Hello
2 World!
3 I
4 Love
5 StackOverflow
listagg()
然后以相反的顺序将它拼凑回来。
答案 1 :(得分:6)
创建功能:
REGEXP_SUBSTR('Your text here','[^ ]+', 1, ?)
将使用Space作为分隔符从文本中提取单词。 Tt在Exception上返回原始String本身!
CREATE OR REPLACE FUNCTION reverse_words (v_STRING IN VARCHAR2)
RETURN VARCHAR2
IS
L_TEMP_TEXT VARCHAR2(4000);
L_FINAL_TEXT VARCHAR2(4000);
V_LOOPCOUNT NUMBER :=0;
T_WORD VARCHAR2(4000);
BEGIN
L_TEMP_TEXT := regexp_replace(V_STRING,'[[:space:]]+',' '); -- Replace multiple spaces as single
LOOP
v_LOOPCOUNT := v_LOOPCOUNT+1;
T_WORD := REGEXP_SUBSTR(L_TEMP_TEXT,'[^ ]+', 1, V_LOOPCOUNT);
L_final_TEXT := T_WORD||' '||L_final_TEXT;
EXIT WHEN T_WORD IS NULL;
END LOOP;
RETURN(TRIM(L_final_TEXT));
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(sqlerrm||chr(10)||dbms_utility.format_error_backtrace);
RETURN V_STRING;
END reverse_words;
/
示例结果:
您可以致电reverse_words(yourcolumn) from your_table
SQL> select reverse_words('Hello World! I Love StackOverflow') "Reversed" from dual;
Reversed
--------------------------------------------------------------------------------
StackOverflow Love I World! Hello
答案 2 :(得分:3)
你走了:
WITH sel_string AS
(SELECT 'Hello World! I Love StackOverflow' AS fullstring FROM DUAL)
SELECT SUBSTR(fullstring, beg + 1, end_p - beg - 1) AS token
FROM (SELECT beg, LEAD(beg) OVER (ORDER BY beg) AS end_p, fullstring
FROM (SELECT beg, fullstring
FROM (SELECT LEVEL beg, fullstring
FROM sel_string
CONNECT BY LEVEL <= LENGTH(fullstring))
WHERE INSTR(' ', SUBSTR(fullstring, beg, 1)) > 0
UNION ALL
SELECT 0, fullstring FROM sel_string
UNION ALL
SELECT LENGTH(fullstring) + 1, fullstring FROM sel_string))
WHERE end_p IS NOT NULL AND
end_p > beg + 1
ORDER BY ROWNUM DESC;
一体化SQL查询。我希望我可以为这个查询声称自己,但我不能 - 几年前在网上找到它并且从那时起就使用过它。
分享并享受。
答案 3 :(得分:3)
还有一个解决方案
WITH str_tab(str1, rn) AS
(SELECT regexp_substr(str, '[^\[:space:]]+', 1, LEVEL),
LEVEL
FROM (SELECT 'Hello World! I Love StackOverflow' str
FROM dual) tab
CONNECT BY LEVEL <= LENGTH(str) - LENGTH(REPLACE(str, ' ')) + 1)
SELECT listagg(str1, ' ') WITHIN GROUP (ORDER BY rn DESC) AS new_text
FROM str_tab;
答案 4 :(得分:0)
DECLARE
in_string VARCHAR2(500);
pros_string VARCHAR2(500);
out_string VARCHAR2(800);
spce_cnt NUMBER;
BEGIN
in_string := 'Hello World! I Love StackOverflow';
pros_string := ' '||in_string||' ' ;
spce_cnt := REGEXP_COUNT(pros_string,' ',1);
FOR i IN reverse 1.. spce_cnt-1
LOOP
out_string := out_string||' '|| SubStr (pros_string,InStr(pros_string, ' ',1,i)+1 ,InStr(SubStr (pros_string,InStr(pros_string, ' ',1,i)+1 ),' ' ));
Dbms_Output.Put_Line(out_string);
END LOOP;
END;