• ベストアンサー

正規表現で少し複雑な置換がしたい

Javaというよりも、正規表現について質問です。 (一応、言語はJavaで、String#replaceAllを使います) 以下のルールで与えられた文字列の置換を行う正規表現を考えていますが、なかなかうまくいきません。 1.正規表現で \w+:: にマッチする文字列を削除する。 2.ただし、'' (シングルクォーテーション)で囲われている文字列は   1.の対象としない 3.ただし、\' (シングルクォーテーションの前に\があった場合は)   シングルクォーテーションと認識しない。 例: 置換前  A * B \'' CCC.DD::EEE' FFF.GGG::HH ' III' 置換後  A * B \'' CCC.DD::EEE' FFF.HH 'III' 色々試してみたのですが、どうしてもうまくいきません。 正規表現が得意な方、教えていただけますでしょうか・・?

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

> 置換前  A * B \'' CCC.DD::EEE' FFF.GGG::HH ' III' > 置換後  A * B \'' CCC.DD::EEE' FFF.HH 'III' 最後の部分が、置換前は ' III' と空白があるのに置換後は 'III' になっているのは何かの間違いですか? import java.lang.*; import java.util.regex.*; public class Ans9479 { /*** 1.正規表現で \w+:: にマッチする文字列を削除する。 2.ただし、'' (シングルクォーテーション)で囲われている文字列は   1.の対象としない 3.ただし、\' (シングルクォーテーションの前に\があった場合は)   シングルクォーテーションと認識しない。 例: 置換前  A * B \'' CCC.DD::EEE' FFF.GGG::HH ' III' 置換後  A * B \'' CCC.DD::EEE' FFF.HH 'III' **/ public static void main(String[] args) { String test_data = "A * B \\'' CCC.DD::EEE' FFF.GGG::HH ' III'"; String test_result = "A * B \\'' CCC.DD::EEE' FFF.HH ' III'"; String pat = "\\G((?:(?:(?<!\\\\)'[^']*')|(?:\\w*?\\W*?))*)\\w+::"; String result = test_data.replaceAll(pat, "$1"); System.out.println(test_data); System.out.println(result); System.out.println(test_result); if (test_result.equals(result)) { System.out.println("あってるっぽい"); } else { System.out.println("だめじゃね?"); } } } 実行結果: A * B \'' CCC.DD::EEE' FFF.GGG::HH ' III' A * B \'' CCC.DD::EEE' FFF.HH ' III' A * B \'' CCC.DD::EEE' FFF.HH ' III' あってるっぽい すげー危ないパターンなので、食わせるデータによってはとんでもなく 時間がかかって死ねます。 改良できるけど眠いのでやらない。

1year365
質問者

お礼

ありがとうございます。 まさに求めていたモノです。 しかし・・・複雑ですね。 \\Gとか?:とか?<!とか使ったことないものが沢山出てきました。 色々と研究してみます。 現実的にはメンテナンス性が低そうなのでダメかもしれませんが、 勉強になりました。

その他の回答 (1)

  • tanida
  • ベストアンサー率0% (0/2)
回答No.1

正規表現だけで''(シングルクォーテーション)で囲まれていない文字列の一部分を指定するのは難しいような気がします(できるのだろうか??おもいつきません)。そもそもどこからどこまで''に囲われているかを判定はどうするのか?? 最初に指定の条件に沿って文字列を区切り、 ''に囲われている文字列以外に対して、 \w+:: にマッチする文字を削除する。 最後に区切った文字を連結するとかいう方法ではだめですか? A * B \' ' CCC.DD::EEE'→対象外 FFF.GGG::HH ' III'→対象外 あまり答えになっていないかもしれませんが。。 以上

1year365
質問者

お礼

ありがとうございます。 ::をマッチさせるときに ' が二つごとにあれば(偶数であれば) というマッチができればできなくは無いと思いました。

関連するQ&A