Groovy学習4 正規表現を使用し、データをまとめて取り出す

GroovyをUbuntuにインストールして勉強中。

Ubuntu 12.10にGroovy 2.1.9をインストールする(GVM:Groovy enVironment Manager使用)
Groovy学習1 groovyシェル、Hello, World、変数、リストとマップ
Groovy学習2 クロージャ、ファイル処理、文字列処理
Groovy学習3 正規表現


チュートリアルを試した時のメモを残しておきます。

Japanese Tutorial 5 - Capturing regex groups
こちらを参考に進めて行きました。




データをまとめて取り出す



よくわからなかったので、いきなり実践で試してみました。


例えば、こんな文字列があるとします。

A1,B1 C1



A1の後にカンマ区切りでB1と続き、半角スペースが入ってC1。

「A1」「B1」「C1」という値を取得したい時は、こんな正規表現を使えばよいようです。
※()でくくった中にマッチする正規表現が取得できる

/([A-Z0-9]+),([A-Z0-9]+) ([A-Z0-9]+)/



「=~」演算子を使用して、Matcherを取得。得られたデータを表示してみます。



  1. locationData = 'A1,B1 C1'
  2. myRegularExpression = /([A-Z0-9]+),([A-Z0-9]+) ([A-Z0-9]+)/
  3. matcher = ( locationData =~ myRegularExpression )
  4. println matcher[0][0]
  5. println matcher[0][1]
  6. println matcher[0][2]
  7. println matcher[0][3]



sample.grvという名前で保存し、groovy sample.grvを実行してみると、こんな結果が得られました。


$ groovy sample.grv
A1,B1 C1
A1
B1
C1




・結果は二次元配列で返される。
・match[0][0]は、マッチした文字列そのもの
・match[0][1]以降に()内の正規表現にマッチする結果が入っている。

というルールの模様。



match[1]ってどういう時に使用するんだろう?ということで別のサンプルを考えてみます。
例えばカンマ区切りの文字列

A1,B1,C1



「A1」「B1」「C1」という値を取得したいので、こんな正規表現にしてみました。

/([A-Z0-9]+)/




以下のプログラムを実行してみます。


  1. locationData = 'A1,B1,C1'
  2. myRegularExpression = /([A-Z0-9]+)/
  3. matcher = ( locationData =~ myRegularExpression )
  4. println matcher[0]
  5. println matcher[1]
  6. println matcher[2]




想定通りの結果です。


$ groovy sample.grv
[A1, A1]
[B1, B1]
[C1, C1]




htmlファイルの中でリンクの文字列を抽出するってことが簡単に行えますね。
雑なプログラムですが、http://symfoware.blog68.fc2.com/blog-entry-1170.htmlからリンクを取得するには
こんな感じになるかと思います。


  1. data = new URL('http://symfoware.blog68.fc2.com/blog-entry-1170.html').text
  2. myRegularExpression = /<a href="([^"]+)/
  3. matcher = ( data =~ myRegularExpression )
  4. matcher.each{ println it[1] }




実行してみると、いい感じの結果が得られました。


$ groovy sample.grv
http://x6.ootugomori.com/bin/gg?082259700
http://estloan.rentalurl.net
http://allelectric.rentalurl.net
http://symfoware.blog68.fc2.com/
http://symfoware.blog68.fc2.com/blog-entry-1170.html
http://symfoware.blog68.fc2.com/blog-entry-1167.html
http://symfoware.blog68.fc2.com/blog-entry-1168.html
http://symfoware.blog68.fc2.com/blog-entry-1169.html
http://groovy.codehaus.org/Japanese+Tutorial+4+-+Regular+expressions+basics
blog-entry-1169.html
blog-entry-1168.html
blog-entry-1167.html
blog-entry-1166.html
(...略)



これは便利。







データの一部を除外して取り出す



正規表現の指定に一味加えることで、データの一部を除外して取得することができます。
まだ完全には理解していなのですが「?:」という指定がミソの模様。

例えば、

A1,B1,C1,D1


というカンマ区切りのデータがあるとして、A1(最初)とD1(最後)だけ欲しい。

そんな時は、こんなプログラムで取り出せました。


  1. data = 'A1,B1,C1,D1'
  2. myRegularExpression = /([A-Z0-9]+)(?:,.+)+,(.*)/
  3. matcher = ( data =~ myRegularExpression )
  4. matcher.each{ println it[1] + 'と' + it[2] }




実行結果は以下のとおり。

$ groovy sample.grv
A1とD1








データの置換



例えばこんなデータがあるとして

ABC123abc123ABC



ABC、まはたabcの部分ををXXXに置換してみます。
まずは、ABCとabcの部分だけ取得するプログラム。


  1. data = 'ABC123abc123ABC'
  2. myRegularExpression = /(ABC|abc)/
  3. matcher = ( data =~ myRegularExpression )
  4. matcher.each{ println it[1] }




実行してみると、狙い通りの箇所が取得できているようです。


$ groovy sample.grv
ABC
abc
ABC





これを置換するには、「matcher.replaceAll([置換する文字列])」を使用します。


  1. data = 'ABC123abc123ABC'
  2. myRegularExpression = /(ABC|abc)/
  3. matcher = ( data =~ myRegularExpression )
  4. matcher.each{ println it[1] }
  5. excerpt = matcher.replaceAll('XXX')
  6. println excerpt





ちゃんと狙った位置の文字列が置換出来ました。


$ groovy sample.grv
ABC
abc
ABC
XXX123XXX123XXX


関連記事

コメント

非公開コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ