文字列を検索する
実行環境
- OS:Windows XP
- Groovy Version: 1.6.5
- JVM: 1.6.0_12
ソースと結果
パターンが含まれるかどうかを調べる
ソース
println "パターンが含まれるかどうかを調べる" ("a c"=~/[ \t]/).find() ("abc"=~/[ \t]/).find() (~/[ \t]/).matcher("a c").find() (~/[ \t]/).matcher("abc").find()
結果
パターンが含まれるかどうかを調べる ===> null ===> true ===> false ===> true ===> false
↑これが正解。Matcher#find()の復帰値はboolean。
(str=~pattern)と(~pattern).matcher(str)が同じ。
ソース
println " 全体一致なのでNG" ("a c"==~/[ \t]/) ("abc"==~/[ \t]/) "a c".matches(/[ \t]/) "abc".matches(/[ \t]/) ("a c"=~/[ \t]/).matches() ("abc"=~/[ \t]/).matches()
結果
全体一致なのでNG ===> null ===> false ===> false ===> null ===> false ===> false ===> false ===> false
↑==~の場合は完全一致、Matcher#mathes()も完全一致。そのためfalseになる。
=~は部分一致。
ソース
println " 左辺と右辺が逆なのでNG" (/[ \t]/==~"a c") (/[ \t]/==~"abc") (/[ \t]/=~"a c").find() (/[ \t]/=~"abc").find()
結果
左辺と右辺が逆なのでNG ===> null ===> false ===> false ===> false ===> false
↑正規表現のパターンと検索対象の文字列が逆
Rubyの人だとこう書きそう。だけど逆なんだよね。
なんで中途半端にまねたんだろ。
ソース
println " Matcherオブジェクトが返されるのでNG" ("a c"=~/[ \t]/) ("abc"=~/[ \t]/)
結果
Matcherオブジェクトが返されるのでNG ===> null ===> java.util.regex.Matcher[pattern=[ \t] region=0,3 lastmatch=] ===> java.util.regex.Matcher[pattern=[ \t] region=0,3 lastmatch=]
ソース
println " マッチした文字列が返されるのでNG" "a c".find(/[ \t]/) "abc".find(/[ \t]/)
結果
マッチした文字列が返されるのでNG ===> null ===> ===> null
↑String#find(Pattern pattern) は文字列が返されるため。
パターンが出現するバイト位置を調べる
ソース
println "パターンが最初に出現するバイト位置を調べる" "xxxabcabcabcxxx".indexOf("abc") "xxxabcabcabcxxx".indexOf(".") "xxx..........xxx".indexOf(".") println "パターンが最後に出現するバイト位置を調べる" "xxxabcabcabcxxx".lastIndexOf("abc") "xxxabcabcabcxxx".lastIndexOf(".") "xxx..........xxx".lastIndexOf(".")
結果
パターンが最初に出現するバイト位置を調べる ===> null ===> 3 ===> -1 ===> 3 パターンが最後に出現するバイト位置を調べる ===> null ===> 9 ===> -1 ===> 12
↑出現しない場合は-1になる。
マッチの詳しい情報を得る
ソース
println "マッチの詳しい情報を得る" str = "xxxabcabcabcxxx" pattern = /abc/ m = (str=~pattern) m.find() m.start() m.end() m[0] str.substring( m.start(), str.length() ) m2 = (~pattern).matcher(str) m2.find() m2.start() m2.end() m2[0] str.substring( m2.start(), str.length() )
結果
マッチの詳しい情報を得る ===> null ===> xxxabcabcabcxxx ===> abc ===> java.util.regex.Matcher[pattern=abc region=0,15 lastmatch=] ===> true ===> 3 ===> 6 ===> abc ===> abcabcabcxxx ===> java.util.regex.Matcher[pattern=abc region=0,15 lastmatch=] ===> true ===> 3 ===> 6 ===> abc ===> abcabcabcxxx
↑最後のRubyのpost_match相当がもっと簡単にできないだろうか?
1つもの文字列中のすべての候補にマッチさせる
ソース
println "1つの文字列中のすべての候補にマッチさせる" str2 = "あ\n aadかきe\ne さ0\n0aた\n iiな\n" m3 = (~/[あ-ん]+/).matcher(str2) m3.find() m3.each {println it}
結果
1つの文字列中のすべての候補にマッチさせる ===> null ===> あ aadかきe e さ0 0aた iiな ===> java.util.regex.Matcher[pattern=[あ-ん]+ region=0,24 lastmatch=] ===> true あ かき さ た な ===> java.util.regex.Matcher[pattern=[あ-ん]+ region=0,24 lastmatch=]
↑each該当するもの分ループさせる。
パターンを含む行のみを処理する
ソース
println "パターンを含む行のみを処理する" str2.findAll(~/.*[あた].*/) { println it} str2.findAll(~/.*[あた].*/) { line->println line} println "NG" str2.findAll(~/[あた]/) { line->println line} 結果 >|groovy| パターンを含む行のみを処理する ===> null あ 0aた ===> [null, null] あ 0aた ===> [null, null] NG ===> null あ た ===> [null, null]
↑findAllだと該当の文字列になるので/[あた]/だとだめ。