web-dev-qa-db-ja.com

Oracle REGEXP_LIKEとWordの境界

Wordの境界とREGEXP_LIKEの一致に問題があります。次のクエリは、期待どおりに単一の行を返します。

select 1 from dual
where regexp_like('DOES TEST WORK HERE','TEST');

しかし、単語の境界についても一致させたいと思います。したがって、「\ b」文字を追加すると、このクエリが得られます

select 1 from dual
where regexp_like('DOES TEST WORK HERE','\bTEST\b');

これを実行すると、ゼロ行が返されます。何か案は?

32
Greg Reynolds

やってみたいと思います

 select 1 from dual 
  where regexp_like ('does test work here', '(^|\s)test(\s|$)');

なぜなら \bはこのリストに表示されません: http://download.Oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_regexp.htm#i100767

\sは、テストが空白で開始および終了することを確認します。ただし、文字列testは、一致する文字列の先頭または末尾にも出現する可能性があるため、これでは不十分です。したがって、私はalternative|^文字列の開始と$文字列の終わり。

更新(3年後+)...たまたま、この機能が必要だったので、正規表現の方が優れているようです(^|\s|\W)test($|\s|\W)Oracleで欠落している\ b正規表現特殊文字 )。

49

一般的に、私はルネの解決策に固執しますが、長さゼロのマッチが必要な場合は例外です。つまり、Word以外の文字を最初/最後に実際にキャプチャする必要はありません。

たとえば、文字列が_test test_の場合、_(\b)test(\b)_は2回一致しますが、_(^|\s|\W)test($|\s|\W)_は最初の一致のみに一致します。少なくとも、regexp_substrを使用しようとする場合は確かにそうです。

SELECT regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 1, 'i'), regexp_substr('test test', '(^|\s|\W)test($|\s|\W)', 1, 2, 'i') FROM dual;

戻り値

_test |NULL_

1
ScottTracy

OracleでWord全体をチェックできる最短の正規表現は

(^|\W)test($|\W)

regexデモ を参照してください。

詳細

  • (^|\W)-いずれかに一致するキャプチャグループ
    • ^-文字列の開始
    • |-または
    • \W-Word以外の文字
  • test-単語
  • ($|\W)-いずれかに一致するキャプチャグループ
    • $-文字列の終わり
    • |-または
    • \W-Word以外の文字。

\Wは、文字、数字、_以外のすべての文字に一致することに注意してください。 _(アンダースコア)の間に出現する可能性のある単語に一致させる場合は、少し異なるパターンが必要です。

(^|[^[:alnum:]])test($|[^[:alnum:]])

[^[:alnum:]]否定ブラケット式は、英数字以外の任意の文字に一致し、_にも一致するため、_test_はこのパターンに一致します。

この正規表現のデモ を参照してください。

1