Groovyで文字列を置換する
正規表現にマッチした部分を固定の文字列に置換する
文字列のうち最初にマッチした1つだけを置換するなら、String#replaceFirstを使う。
マッチした全てを置換するなら、String#replaceAllを使う
ソース
ai = "あいあいあい" println "置換前:" + ai println "置換後 :" + ai.replaceFirst(/あい/,"愛") println "置換しても元の文字列には影響はにない" + ai println "" println "置換後 :" + ai.replaceAll(/あい/,"愛") println "" test="abcdefg" println "置換前:" + test println "置換後 :" + test.tr("acg","ACG") println "" println "置換前:" + ai println "置換後:" + ai.tr("い","お") println "" println "置換前:" + ai println "置換後:" + ai.tr("あい","愛")
実行結果
[D:\workspace\groovy_SandBox]groovy Q052_文字列の一部を置換する.groovy 置換前:あいあいあい 置換後 :愛あいあい 置換しても元の文字列には影響はにないあいあいあい 置換後 :愛愛愛 置換前:abcdefg 置換後 :AbCdefG 置換前:あいあいあい 置換後:あおあおあお 置換前:あいあいあい 置換後:愛愛愛愛愛愛
正規表現にマッチした部分を式の実行結果の文字列に置換する
固定文字列ではなく、式の実行結果の文字列に置換するなら、Clousure(クロージャー)を
使う。
ソース
if( org.codehaus.groovy.runtime.InvokerHelper.getVersion() < "1.7.7" ) { println "Groovy 1.7.7以上が必要です" return } queue = ["愛","哀","相"] i=0 println "あいあいあい".replaceFirst(/あい/) { queue[i++] } i=0 println "あいあいあい".replaceAll(/あい/) { queue[i++] } queue = ["愛","哀","相"] println "あいあいあい".replaceFirst(/あい/) { queue.pop() } queue = ["愛","哀","相"] println "あいあいあい".replaceAll(/あい/) { queue.pop() } println "" println "FrontPage".replaceFirst(/(.)([A-Z])/){it[1] + " " + it[2]} println "MyToDo".replaceAll(/(.)([A-Z])/){it[1] + " " + it[2]}
実行結果
[D:\workspace\groovy_SandBox]groovy Q052_文字列の一部を置換する2.groovy 愛あいあい 愛哀相 相あいあい 相哀愛 Front Page My To Do
補足
1.7.7以降
1.0以降
replaceFirstとreplaceAllとでずいぶんサポートした時期に差があるんだな。
Rubyのshift()メソッドの代わりはpop()で。
Groovy イン・アクション p90より
リストは①のようにプッシュ(push)やポップ(pop)といった一般的なスタック操作によって
スタックのように扱うことができます。プッシュ操作は、リストの左シフト演算子(<<)に
割り当てられています。
iを使った配列の操作でもいいが、Groovyぽっく各とすると後者のpopになるのだろうか。
でも、スタックなので、一度空になってしまうので、リストを2度定義する必要がある。
それがなんかいやだな。
"FrontPage".replaceFirst(/(.)([A-Z])/){it[1] + " " + it[2]}
で
itの中身は[tP, t, P]のようになる。
そのため、置換後の文字列を使うには、it[1],it[2]を使う。
範囲を指定して置換する
ソース
result = ['N','a','m','a','z','u'] println result result[1..1] = 'u' println result result = "Numa-" result[0,1] = 'k' println result
実行結果
[D:\workspace\groovy_SandBox]groovy Q052_文字列の一部を置換する3.groovy [N, a, m, a, z, u] [N, u, m, a, z, u] Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.String.putAt() is applicable for argument types: (groovy.lang.IntRange, java.lang.String) values: [0..1, k] Possible solutions: putAt(java.lang.String, java.lang.Object), getAt(groovy.lang.IntRange), getAt(groovy.lang.IntRange), getAt(java.lang.String), getAt(groovy.lang.Range), getAt(groovy.lang.Range)
補足
result[0..1] = 'k' に変更してもダメだった。。
result = "Numa-" result[0..1] = 'k' println result
Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.String.putAt() is applicable for argument types: (java.util.ArrayList, java.lang.String) values: [[0, 1], k] Possible solutions: putAt(java.lang.String, java.lang.Object), getAt(java.lang.String), getAt(groovy.lang.EmptyRange), getAt(groovy.lang.EmptyRange), getAt(groovy.lang.Range), getAt(groovy.lang.Range)
Rubyだとが出来るようだが、Groovyではダメのようだ。
result = "Numa-" result[0..1] = 'k' p result #=> "Kuma-"
String自身は配列じゃないからかな?
実行環境
- OS:Windows XP
- Groovy Version: 1.7.8
- JVM: 1.6.0_12
replaceFirst(String regex, Closure closure)が1.7.7以降のため、Groovyのバージョンがいつもと違う。
Groovyの詳細についてはJavadocと以下の書籍を参考にしている。
Dierk Konig、Andrew Glover、Paul King、、Guillaume Laforge、Jon Skeet、杉浦 孝、櫻井 正樹、須江 信洋、関谷 和愛、佐野 徹郎、寺沢 尚史
出品者からお求めいただけます。価格は記載時点のものです。購入前にAmazonでご確認ください。
問題自体は第2版のもの。rubyと似てる部分も多いので、ヒントにもなる。
写経でもいいが自分で考えるために他言語の例をGroovyで置き換えてる。
Groovyイン・アクションを読むならあった方が便利かな。