web-dev-qa-db-ja.com

Java:文字列内のすべての 'を\'に置き換えます

文字列内のすべての引用符( ')をエスケープする必要があるため、\'になります

ReplaceAllを使用してみましたが、何も実行されません。何らかの理由で、正規表現を機能させることができません。

私はしようとしています

String s = "You'll be totally awesome, I'm really terrible";
String shouldBecome = "You\'ll be totally awesome, I\'m really terrible";
s = s.replaceAll("'","\\'"); // Doesn't do anything
s = s.replaceAll("\'","\\'"); // Doesn't do anything
s = s.replaceAll("\\'","\\'"); // Doesn't do anything

私は本当にここで立ち往生しています。誰かがここで私を助けることができることを願っています。

おかげで、

イワン

21
Iwan Eising

バックスラッシュはリテラルであるため、最初にエスケープする必要があります(\\)、そして正規表現のために再びエスケープします(\\\\)。だから、試してみてください:

 s.replaceAll("'", "\\\\'");

出力:

You\'ll be totally awesome, I\'m really terrible
31
Sage

replace() を使用します

 s = s.replace("'", "\\'"); 

出力:

あなたは完全に素晴らしいでしょう、私は本当にひどいです

12
kosa

String#repalceAll(String regex、String replacement) のツアーを見てみましょう

あなたはそれを見るでしょう:

このメソッドをstr.replaceAll(regex、repl)の形式で呼び出すと、式とまったく同じ結果が得られます

Pattern.compile(regex).matcher(str).replaceAll(repl)

それでは Matcher.html#replaceAll(Java.lang.String) ドキュメントを見てみましょう

置換文字列にバックスラッシュ(\)とドル記号($)を使用すると、リテラル置換文字列として処理された場合とは結果が異なる場合があることに注意してください。 ドル記号は、上記のようにキャプチャされたサブシーケンスへの参照として扱われ、バックスラッシュは、リテラル文字をエスケープするために使用されます置換文字列

replacementには、キャプチャされたグループへの参照として使用できる特殊文字$があることがわかります。

System.out.println("aHellob,aWorldb".replaceAll("a(\\w+?)b", "$1"));
// result Hello,World

ただし、$を単純なドル文字として使用したいために特別なものにしたくない場合があるため、エスケープする方法が必要です。
これが\です。これは、正規表現、文字列、およびおそらく他の場所でメタ文字をエスケープするために使用されるため、ここで$をエスケープするために使用するのは良い慣習だからです。

したがって、\も置換部分のメタ文字であるため、単純な\リテラルに置き換えたい場合は、なんとかしてエスケープする必要があります。そして、何を推測しますか?正規表現や文字列でエスケープするのと同じ方法でエスケープします。エスケープする前に、別の\を配置するだけです。

したがって、置換パーツに\を作成する場合は、その前に別の\を追加する必要があります。ただし、\リテラルを文字列で書き込むには、"\\"として書き込む必要があるため、2つの\\を作成して置き換えるには、"\\\\"として書き込む必要があります。


だから試して

s = s.replaceAll("'", "\\\\'");

またはさらに良い

置換部分(および正規表現部分も-前に言及したことを忘れた)での明示的なエスケープを減らすには、代わりにreplaceを使用しますreplaceAllこれにより、正規表現のエスケープが追加されます

s = s.replace("'", "\\'");
9
Pshemo

これは、問題を「修正」する方法を示していません-それはすでに他の回答で行われています。詳細と該当するドキュメントの参照を引き出すために存在します。


String.replaceAll または該当するMatcher置き換えのいずれかで、置き換え文字列とその処理方法に注意してください。

バックスラッシュ(\)とドル記号($)置​​換文字列を使用すると、リテラル置換文字列として処理された場合と結果が異なる場合があります。ドル記号は、上記のようにキャプチャされたサブシーケンスへの参照として処理され、置換文字列内のリテラル文字をエスケープします。

Isnot2badがコメントで指摘しているように、 Matcher.quoteReplacement ここで役立つかもしれません:

指定された文字列のリテラル置換文字列を返します。 ..生成される文字列は、リテラルシーケンスとして扱われるsの文字シーケンスと一致します。スラッシュ(\)とドル記号($)には特別な意味はありません。

3
user2864740

StringEscapeUtilsのようなものを使用して、人生をさらに簡単にすることもできます: http://commons.Apache.org/proper/commons-lang/javadocs/api-2.6/org/Apache/commons/lang/StringEscapeUtils .html

s = StringEscapeUtils.escapeJava(s);
1
LeoPleurodon