2012-03-11 13 views
7

私はずっと喜んでRegex replaceAllInを実行していましたが、replacement文字列の中に正規表現のようなものがあると問題に遭遇しました。以下にその問題を示します(Scala 2.9.1-1)。簡単な解決策を使用してのアイデアは本当に批判に耐えないので、本当の問題空間がはるかに複雑であることに注意してください(単に避けられ先取りする「あなたがしようとしないのはなぜ...」を:D)置き換え文字列が正規表現のように見える場合、scala regex replaceAllInは置き換えられませんか?

val data = "val re = \"\"\"^[^/]*://[^/]*/[^/]*$\"\"\".r" 
val source = """here 
LATEX_THING{abc} 
there""" 
val re = "LATEX_THING\\{abc\\}".r 
println(re.replaceAllIn(source, data)) 

これは、次のエラーを呈する:私はそれはのような単純なものにしたものから、dataを変更した場合は

java.lang.IllegalArgumentException: Illegal group reference 

val data = "This will work" 

そして、すべての罰金を。

replaceAllInは何とか2番目の文字列を探していて、最初のREから覚えていたものを参照する別のREとして使用していますが、ドキュメントには何も言いません。

私には何が欠けていますか?

編集

re.replaceAllIn(source, java.util.regex.Matcher.quoteReplacement(data)) 

答えて

9

あなたの置換文字列で$をエスケープする必要があります:

val data = "val re = \"\"\"^[^/]*://[^/]*/[^/]*\\$\"\"\".r" 
[OK]を、 java.util.regex.Matcherクラスを見た後、意図した修正があると思われるので、

それ以外の場合は、グループ参照の先頭と解釈されます($に1つ以上の数字が続いた場合にのみ有効です)。詳細についてはjava.util.regex.Matcherためthe documentationを参照してください:

The replacement string may contain references to subsequences captured during the previous match: Each occurrence of $g will be replaced by the result of evaluating group(g) ... A dollar sign ($) may be included as a literal in the replacement string by preceding it with a backslash (\$).

Updateはあなたのコメントに対処し、上記編集する:あなたがある場合は、私が推測する(文字列リテラルでの作業が、エスケープしていない場合は、[はい、あなたはMatcher.quoteReplacementを使用することができますその場合には$がより簡単に見えます)、があります。これはscala.util.matching.Regexの方法としてquoteReplacementが今後利用できるようになります。

+1

ありがとうございます。 Javaのドキュメントに向かうのは私には起こりませんでした。それは、本当のJavaのコーダーではないということです。問題の 'data'は実際にはScalaのソースファイルから来ています。あなたが持っているものを正確に知っていないかぎり、 '$'を '$ $ 'に置き換えて最初に前処理して、それをあなたが望むように処理するという経験則があると思います。 –

関連する問題