2016-12-16 11 views
0

ご存じのように、Oracle POSIXのregexes実装ではワード境界がサポートされていません。 1つの回避策をここに示唆します: Oracle REGEXP_LIKE and word boundariesOracle regexp_likeワード境界複数ワード回避策

しかし、私はすべての4文字列を選択したい場合は動作しません。たとえば、次のように考えてみてください。

myvar:=regexp_substr('test test','(^|\s|\W)[\S]{4}($|\s|\W)') 

これは明らかに最初のオカレンスだけを選択します。私はOracleの世界でこれを行う方法はわかりませんが、通常は単に(\b)[\S]{4}(\b)です。問題は、ほとんどのワーキングアラウンドは、ルックアラウンドのような存在しない機能に依存していることです。

答えて

0
select xmlcast(xmlquery('for $token in ora:tokenize(concat(" ",$in)," ") 
       where string-length($token) = $size 
       return $token' passing 'test test' as "in", 4 as "size" returning content) as varchar2(2000)) word from dual; 

XqueryおよびFLWOR expresion。

concat(" ",$in) - 入力文字列がヌルであるか、一致する単語が1つしかない場合の回避策です。

ora:tokenize - "スペース" によってトークン化文字列

string-length($token) = $sizeチェックトークンは、適切な長さを持っている場合。

xmlcast - XMLTypeのは

簡単にVARCHAR2に変換しますか?ご質問:)(REGEXP_COUNTまたは11Gに導入されたREGEXP_SUBSTRの第六パラメータを使用せずに)

+0

Oracle XMLを使用して素晴らしいソリューションを多数見てきましたが、私はそれについて全く知らないです。誰かが私を始めさせるために本やウェブサイトを勧めてもいいですか? –

0
DECLARE 
    str  VARCHAR2(200) := 'test test'; 
    pattern VARCHAR2(200) := '(\w+)($|\s+|\W+)'; 
    match VARCHAR2(200); 
BEGIN 
    FOR i IN 1 .. REGEXP_COUNT(str, pattern) LOOP 
    match := REGEXP_SUBSTR(str, pattern, 1, i, NULL, 1); 
    IF LENGTH(match) = 4 THEN 
     DBMS_OUTPUT.PUT_LINE(match); 
    END IF; 
    END LOOP; 
END; 
/

か:

DECLARE 
    str    VARCHAR2(200) := 'test test'; 
    pattern CONSTANT VARCHAR2(3) := '\w+'; 
    match   VARCHAR2(200); 
    i    NUMBER(4,0) := 1; 
BEGIN 
    match := REGEXP_SUBSTR(str, pattern, 1, i); 
    WHILE match IS NOT NULL LOOP 
    IF LENGTH(match) = 4 THEN 
     DBMS_OUTPUT.PUT_LINE(match); 
    END IF; 
    i  := i + 1; 
    match := REGEXP_SUBSTR(str, pattern, 1, i); 
    END LOOP; 
END; 
/

出力

test 
test 

したい場合これをSQLで使用するには、パイプライン関数またはコレクションを返す関数に簡単に変換できます。

+0

ありがとうございました。残念ながら、私は10gです。REGEXP_COUNTは利用できません。私は彼らが11gでそれを紹介したと思う。 – Dimiter

+0

@Dimiter(うまくいけば)Oracle 10gソリューションを追加しました。 – MT0

+0

@MTO:どうもありがとう!とても有難い! – Dimiter

関連する問題