Java'da, tırnak işaretlerinden kaçmak zorunda kalmadan değişmez bir dize yazmanın bir yolu var mı?


111

Diyelim ki, içinde çok sayıda tırnak işareti olan bir String değişmezi var. Hepsinden kaçabilirsin ama bu bir acı ve okuması zor.

Bazı dillerde şunu yapabilirsiniz:

foo = '"Hello, World"';

Java'da ''ise chars için kullanılır , bu yüzden Stringbu şekilde kullanamazsınız . Bazı dillerin bu sorunu çözmek için sözdizimi vardır. Örneğin, python'da şunu yapabilirsiniz:

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

Java'da benzer bir şey var mı?



Bu yanıt , Eclispe'de çok satırlı çıkış karakterli dizelerin nasıl yapıştırılacağını gösterir.
Jeff Axelrod

2
2018 Güncellemesi: Java için ham dize değişmezleri geliyor olabilir. Aşağıdaki cevabımı görün
VonC

sonra jackson ObjectMapper'ı içe aktarın System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv

Güncelleştirme S4 2018: Ham dize vardır değil henüz geliyor. Güncellenen cevabıma bakın .
VonC

Yanıtlar:


74

Cevap hayırdır ve kanıt Java Dil Spesifikasyonunda bulunur :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Gördüğünüz gibi StringLiteral, sadece sınırlanabilir "ve kaçışsız özel karakter içeremez ..

Bir yan not: gömebilirsiniz Groovy proje içinde, bu kullanmak için izin Java sözdizimi uzatacaktır '''multi line string ''', ' "string with single quotes" 'ayrıca ve "string with ${variable}".


141

Hayır ve Java'da farklı dizgi-değişmez sözdizimlerinin olmamasından her zaman rahatsız olmuşumdur.

İşte zaman zaman kullandığım bir numara:

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

Genelde böyle bir şeyi sadece statik bir alan için yapıyorum. Statik olduğundan, dizgi değiştirme kodu, sınıf başlatıldığında bir kez çağrılır. Dolayısıyla, çalışma zamanı performans cezası pratik olarak mevcut değildir ve kodu önemli ölçüde daha okunaklı hale getirir.


replaceAll kullanmanız gerekmiyor mu?
Landon Kuhn

10
@ landon9720 Hayır, .replace, bir karakter / karakter dizisinin tüm oluşumlarını başka bir karakter / karakter dizisi ile değiştirir. .replaceAll normal ifadeyi kullanır.
abelito

Meraktan, java derleyicisinin bunu derleme üzerine basitleştirip basitleştirmeyeceğini biliyor musunuz?
ug_

2
Hayır, derleyicinin bunu basitleştireceğini sanmıyorum. Ama gerçekten önemli değil. Bu çok ucuz bir çağrı ve eğer bunu yalnızca statik son dizeler için yaparsam, maliyet sınıf yükleme üzerine yalnızca bir kez yüklenecektir. Bu, daha güzel görünen kod için genellikle ödemeye hazır olduğum bir bedel :)
benjismith

3
O halde myString'deki "\" ne olacak?
Anderson

10

Aralık 2018 güncellemesi (12 ay sonra):

Ham dize değişmezleri ( amber listesindeki ) JDK 12'ye ulaşmayacaktır. Eleştirilere buradan
bakın .


Java'nın gelecekteki bir sürümünde (10 veya üzeri) olabilir.

Ocak 2018 tarihli JEPS 8196004'e bakın : ( "JEP", "JDK Geliştirme Programı" dır )

JEP taslağı: Ham Dize Değişmezleri

Java programlama diline yeni bir tür değişmez, ham dize değişmezi ekleyin.
Geleneksel dize değişmezi gibi, bir ham dize değişmezi bir String üretir, ancak dize kaçışlarını yorumlamaz ve birden çok kaynak kodu satırına yayılabilir .

Yani bunun yerine:

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"));

Şunları yazabilirsiniz:

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`));

Temiz!

Ama yine de sadece bir taslak : tamamlanmadan ve bir sonraki JDK'da yapılmadan önce gönderilmesi, sunulması, aday olması ve finanse edilmesi gerekecek.


5

Basit cevap: Hayır.

Kaçılması gereken daha uzun dizeler için, genellikle onları bazı harici kaynaklardan okurum.


4

apache commons'tan StringEscapeUtils'i de kullanabilirsiniz

GÜNCELLEME : Birisi bazı örneklerle ilgileniyorsa, burada yararlı bir bağlantı vardır: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils


2
Lütfen bu problem için nasıl yapılacağını gösteren soruya dayalı bir örnek ekleyebilir misiniz?
Bengt

3
Yalnızca soruyu yanıtlayabilecek başka bir kaynağa başvurmanın yetersiz olduğu kabul edilir. Lütfen bağlantılı sayfayı soruyla eşleşen bir örnekle özetlemeyi düşünün.
Bengt

Bir baktım ve soruyu gerçekten cevapladığını düşünmüyorum. Statik yöntemlerin girdileri Strings'dir, bu nedenle kodunuzda güzel biçimlendirilmiş bir değere sahip olmanın yolu yoktur. Muhtemelen bu yöntemleri bir dosyadan a'ya okumak için kullanabilirsiniz String, ancak buradaki sorunun bu olduğunu sanmıyorum.
Tom Harrison

Bağlantılı sınıf (org.apache.commons.lang3.StringEscapeUtils) kullanımdan kaldırıldı ve org.apache.commons.text.StringEscapeUtils
jcarter

-4

Aşağıdakiler benim için çalışıyor gibi görünüyor:

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

Sanırım char String için ilkel değişken türü olduğu için, Strings ve chars birleştirilebilir (en azından eclipse derleyicisi şikayetçi görünmüyor).


1
Sanırım char String <için ilkel değişken türü olduğu için - Varsayımınız yanlış. Bu nedenle, int gibi farklı bir türle de çalışacaktır, örneğin: String x = "Bazı metin" + 33 + "Daha fazla metin";
Najeeb

-6

Çıkış yapmak istiyorsanız 'veya "dizenizde aşağıdaki kodu kullanabilirsiniz:

String text = ...

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

Soru, kaynak koddaki dize değişmezleri hakkında soruldu. Üzgünüm, tekrar dene.
michaelb958 - GoFundMonica
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.