読者です 読者をやめる 読者になる 読者になる

正規表現にマッチした部分の前後の文字列を取り出す

Groovy

Groovyの正規表現Javaと同じなので以下で確認
http://java.sun.com/javase/ja/6/docs/ja/api/java/util/regex/Pattern.html#sum

正規表現構文の要約
特殊な構文 (前方参照を行わない)
(?:X) X、前方参照を行わない正規表現グループ
(?idmsux-idmsux) 正規表現ではないが、マッチフラグ i、d、m、s、u、x のオン/オフを切り替える
(?idmsux-idmsux:X) X、前方参照を行わないグループ。指定されたフラグ i、d、m、s、u、x のオン/オフを切り替える
(?=X) X、幅ゼロの肯定先読み
(?!X) X、幅ゼロの否定先読み
(?<=X) X、幅ゼロの肯定後読み
(?X) X、独立した前方参照を行わない正規表現グループ

ニホンゴムズカシイアルネ。。。
幅ゼロの肯定とか幅ゼロの否定ってなんだろう。

マッチしたところの前を取り出す


「この先生きのこるには」から「生きのこる」の前を取り出すには


(?=X) 肯定先読みを使えばいいはず

groovy:000> ("この先生きのこるには" =~ /(?=生きのこる)/).each{println it}

===> java.util.regex.Matcher[pattern=(?=生きのこる) region=0,10 lastmatch=]

ん?だめだぞ。
なんで?


正規表現、先読みと後読み

先読み、後読みは何に使うのかというと、「文字列の前と後にどんな文字が来るか判別したくて、
なおかつその部分にはマッチさせたくない」という場合に使う。
たとえば、「hoge(?=pattern)」は patternが後ろにあるhogeにマッチするが、
(?=pattern)部分にはマッチしない。
「(?<=pattern)hoge」は patternが前にあるhogeにマッチするが、(?<=pattern) 部分には
マッチしない。

java.util.regex クラス Pattern

(?=X) 前方先読みをしてXとマッチ※1
(?!X) 前方先読みをしてXとノンマッチ(==前方にXがない)
(?<=X) 後方振り返り読みをしてXとマッチ
(?X) Xを捕捉グループではない独立的グループと見なす
(所有的・支配的マッチを行なう※2)

〔訳注※1:これら4つの、前方先読みと後方振り返り読みマッチにマッチした部分は、
マッチ本体に含まれないため、ゼロ幅(zero width)マッチと呼ばれる。
たとえばY(?=X)は、前方にXがあるYという意味であり、拾われるマッチ本体はYと
マッチした部分のみです。京都(?=府)は、“京都府”という語句の中の“京都”とマッチします。
京都市の京都とはマッチしません。〕


なるほど、そう言うことか。
(?=X)じゃだめで、hoge(?=X)みたいに使うのね。

groovy:000> ("この先生きのこるには" =~ /.*(?=生きのこる)/).each{println it}
この先
===> java.util.regex.Matcher[pattern=.*(?=生きのこる) region=0,10 lastmatch=]

OK!!

マッチしたところの後ろを取り出す


「この先生きのこるには」から「生きのこる」の後を取り出す


後ろを取り出すのも同じ。(?<=X)じゃだめで、(?<=X)hogeみたいに使う。

groovy:000> ("この先生きのこるには" =~ /(?<=生きのこる)/).each{println  it}

===> java.util.regex.Matcher[pattern=(?<=生きのこる) region=0,10 lastmatch=]
groovy:000> ("この先生きのこるには" =~ /(?<=生きのこる).*/).each{println it}
には
===> java.util.regex.Matcher[pattern=(?<=生きのこる).* region=0,10 lastmatch=]

実行環境







Groovyの詳細についてはJavadocと以下の書籍を参考にしている。
ページ番号は、この書籍のページ番号

Groovyイン・アクション
Dierk Konig Andrew Glover Paul King Guillaume Laforge Jon Skeet
毎日コミュニケーションズ
売り上げランキング: 294340


問題自体は以下の書籍のもの。rubyと似てる部分も多いので、ヒントにもなる。
写経でもいいが自分で考えるために他言語の例をGroovyで置き換えてる。

Rubyレシピブック 第2版 268の技
青木 峰郎 後藤 裕蔵 高橋 征義
ソフトバンク クリエイティブ
売り上げランキング: 80467


Groovyイン・アクションを読むならあった方が便利かな。

ブックストッパー
ブックストッパー
posted with amazlet at 10.05.16

トモエ算盤
売り上げランキング: 614


Rubyレシピブックは「ほんたった」で立ててる

EDISON ほんたった黒(ハードケース入り)
株式会社エジソン
売り上げランキング: 2164