Javaでは、引用符をエスケープすることなく文字列リテラルを書く方法はありますか?


111

引用符がたくさんある文字列リテラルがあるとします。あなたはそれらすべてを脱出することができますが、それは苦痛であり、読むのが難しいです。

一部の言語では、これを行うことができます:

foo = '"Hello, World"';

ただし、Javaでは''がに使用されるためcharStringこの方法でに使用することはできません。一部の言語には、これを回避する構文があります。たとえば、Pythonでは次のようにできます。

"""A pretty "convenient" string"""

Javaにも同様のものはありますか?



この回答は、Eclispeで複数行のエスケープ文字列を貼り付ける方法を示しています。
Jeff Axelrod 2012年

2
2018年更新:Java用の生の文字列リテラルが登場する可能性があります。下記の私の回答を参照してください
VonC、2018年

次に、jackson ObjectMapperをインポートします System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv 2018

2018年第4四半期の更新:未加工の文字列リテラルはまだ登場していません。私の更新された答えを見てください。
VonC、2018

回答:


74

答えは「いいえ」で、証明はJava言語仕様にあります。

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

ご覧のとおり、エスケープなしでは、StringLiteralバインドできるだけで"、特殊文字を含めることはできません。

サイドノート:あなたは埋め込むことができGroovyのを、プロジェクト内で、これはあなたが使用できるようにするJavaの構文を拡張します'''multi line string '''' "string with single quotes" 'とも"string with ${variable}"


141

いいえ、そしてJavaにはさまざまな文字列リテラル構文がないことにいつも悩まされてきました。

ここに私が時々使ったトリックがあります:

String myString = "using `backticks` instead of quotes".replace('`', '"');

私は主に静的フィールドに対してそのようなことをするだけです。静的なので、クラスの初期化時に文字列置換コードが1回呼び出されます。したがって、実行時のパフォーマンスのペナルティは事実上存在せず、コードがかなり読みやすくなります。


replaceAllを使用する必要はありませんか?
Landon Kuhn

10
@ landon9720いいえ。.replaceは、出現するすべての文字/文字シーケンスを別の文字/文字シーケンスに置き換えます。.replaceAllは正規表現を使用します。
アベリト

好奇心から、Javaコンパイラーがコンパイル時にこれを単純化するかどうか知っていますか?
ug_ 2014

2
いいえ、コンパイラがこれを単純化するとは思いません。しかし、それは本当に重要ではありません。これは非常に安価な呼び出しであり、静的な最終文字列に対してのみこれを行う場合、コストはクラスローディング時に1回だけ発生します。これは、より見栄えのよいコードを
購入する

3
では、myStringの「\」はどうでしょうか。
アンダーソン

10

2018年12月の更新(12か月後):

未加工の文字列リテラル(こはく色のリストにある)は、JDK 12に到達しません。批評はこちらを
参照してください


将来のバージョンのJava(10以上)に含まれる可能性があります。

2018年1月のJEPS 8196004を参照してください:(「JEP」は「JDK拡張プログラム」です

JEPドラフト:Raw String Literals

新しい種類のリテラル、生の文字列リテラルをJavaプログラミング言語に追加します。
従来の文字列リテラルと同様に、生の文字列リテラルは文字列を生成しますが、文字列エスケープを解釈せず複数行のソースコードにまたがることがあります

だから代わりに:

Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar");
String html = "<html>\n"
              "    <body>\n" +
              "         <p>Hello World.</p>\n" +
              "    </body>\n" +
              "</html>\n";
System.out.println("this".matches("\\w\\w\\w\\w"));

次のように入力できます。

Runtime.getRuntime().exec(`"C:\Program Files\foo" bar"`);
    
String html = `<html>
                   <body>
                       <p>Hello World.</p>
                   </body>
               </html>
              `;

System.out.println("this".matches(`\w\w\w\w`));

きちんと!

しかし、それはまだドラフトにすぎません。完成して次のJDKにする前に、投稿、提出、候補者、資金提供が必要です。


5

簡単な答え:いいえ。

エスケープする必要のある長い文字列の場合、通常は外部リソースから読み取ります。


4

Apache CommonsのStringEscapeUtilsを使用することもできます

更新:誰かがいくつかの例に興味がある場合、ここに役立つリンクがあります:https : //dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils


2
この問題の解決方法を示す質問に基づいた例を追加していただけませんか?
Bengt 2013年

3
質問に回答する可能性のある別のリソースを参照するだけでは、最適とは言えません。質問に一致する例を使用して、リンクされたページを要約することを検討してください。
Bengt 2013年

調べたところ、どちらも本当の質問には答えられないと思います。静的メソッドへの入力はStringsなので、コードに適切にフォーマットされた値を含める方法はありません。おそらく、これらのメソッドを使用してファイルからに読み込むことができますがString、ここでは問題ではないと思います。
トムハリソン

リンクされたクラス(org.apache.commons.lang3.StringEscapeUtils)は非推奨になり、org.apache.commons.text.StringEscapeUtilsに
jcarter

-4

以下は私にとってはうまくいくようです:

String x = "Some Text" + '"' + "More Text" + '"' + "Even More Text";

charはStringのプリミティブ変数型であるため、Stringとcharsを組み合わせることができます(少なくともEclipseコンパイラーは文句を言わないようです)。


1
charはStringのプリミティブ変数タイプなので、<-あなたの仮定は正しくありません。さらに言えば、intなどの別のタイプでも機能します。Stringx = "Some text" + 33 + "More text";
Najeeb、

-6

エスケープする'場合"、または文字列で使用する場合は、次のコードを使用できます。

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");

ソースコードの文字列リテラルについて質問されました。申し訳ありませんが、もう一度やり直してください。
michaelb958--GoFundMonica 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.