Java에서 따옴표를 이스케이프하지 않고 문자열 리터럴을 작성하는 방법이 있습니까?


111

내부에 따옴표가 많은 문자열 리터럴이 있다고 가정합니다. 당신은 그들 모두를 피할 수 있지만 고통스럽고 읽기가 어렵습니다.

일부 언어에서는 다음과 같이 할 수 있습니다.

foo = '"Hello, World"';

자바 그러나, ''사용되는 char당신이 그것을 사용할 수 있도록의 String이런 식의. 일부 언어에는이 문제를 해결할 수있는 구문이 있습니다. 예를 들어, 파이썬에서는 다음과 같이 할 수 있습니다.

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

Java에도 비슷한 것이 있습니까?



이 답변 은 Eclispe에서 여러 줄 이스케이프 문자열을 붙여 넣는 방법을 보여줍니다.
Jeff Axelrod 2012 년

2
2018 업데이트 : Java 용 원시 문자열 리터럴이 출시 될 수 있습니다. 아래 내 대답을 참조하십시오
VonC

수입 잭슨 ObjectMapper 다음 System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv

업데이트 Q4 2018 : 원시 문자열 리터럴되어 있지 아직오고. 내 업데이트 된 답변을 참조하십시오 .
VonC

답변:


74

대답은 '아니요'이며 그 증거는 Java 언어 사양에 있습니다 .

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

보시다시피 a StringLiteral"이스케이프없이 특수 문자를 포함 할 수 없습니다.

참고 : 프로젝트 내부 에 Groovy 를 임베드 할 수 있습니다 . 이렇게하면 Java 구문이 확장되어 '''multi line string ''', ' "string with single quotes" '"string with ${variable}".


141

아니요, 저는 Java에 다른 문자열 리터럴 구문이 없다는 사실에 항상 짜증이났습니다.

다음은 내가 가끔 사용한 트릭입니다.

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

나는 주로 정적 필드에 대해서만 이와 같은 작업을 수행합니다. 정적이기 때문에 문자열 교체 코드는 클래스 초기화시 한 번 호출됩니다. 따라서 런타임 성능 불이익은 거의 존재하지 않으며 코드를 훨씬 더 읽기 쉽게 만듭니다.


replaceAll을 사용할 필요가 없습니까?
랜든 쿤

10
@ landon9720 아니요, .replace는 문자 / 문자 시퀀스의 모든 발생을 다른 문자 / 문자 시퀀스로 바꿉니다. .replaceAll은 정규식을 사용합니다.
abelito 2012-07-16

호기심에서 자바 컴파일러가 컴파일시 이것을 단순화하는지 알고 있습니까?
ug_

2
아니요, 컴파일러가 이것을 단순화 할 것이라고 생각하지 않습니다. 그러나 그것은 정말로 중요하지 않습니다. 매우 저렴한 호출이며 정적 최종 문자열에 대해서만이 작업을 수행하면 클래스 로딩시 비용이 한 번만 발생합니다. 그건 내가 :) 더 좋은 찾고 코드를 지불 할 일반적으로 기꺼이 가격입니다
benjismith

3
그러면 myString의 "\"는 어떻습니까?
Anderson

10

2018 년 12 월 업데이트 (12 개월 후) :

원시 문자열 리터럴 ( 호박색 목록에 있음 )은 JDK 12에 적용되지 않습니다 . 여기
에서 비판을 참조 하십시오 .


향후 버전의 Java (10 이상)가있을 수 있습니다.

2018 년 1 월의 JEPS 8196004 참조 : ( "JEP"는 "JDK 향상 프로그램"입니다. )

JEP 초안 : 원시 문자열 리터럴

Java 프로그래밍 언어에 새로운 종류의 리터럴 인 원시 문자열 리터럴을 추가합니다.
전통적인 문자열 리터럴과 마찬가지로 원시 문자열 리터럴은 String을 생성하지만 문자열 이스케이프를 해석하지 않으며 여러 줄의 소스 코드에 걸쳐있을 수 있습니다 .

그래서 대신 :

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

3
질문에 답할 수있는 다른 리소스 만 참조하는 것은 차선책으로 간주됩니다. 질문과 일치하는 예제로 링크 된 페이지를 요약 해보십시오.
Bengt

나는 한 번 살펴 보았지만 질문에 실제로 대답하지 않는다고 생각합니다. 정적 메서드에 대한 입력은 Strings이므로 코드에서 형식이 좋은 값을 가질 방법이 없습니다. 아마도 이러한 방법을 사용하여 파일에서 .NET 파일로 읽을 수는 String있지만 여기에서는 이것이 문제라고 생각하지 않습니다.
Tom Harrison

링크 된 클래스 (org.apache.commons.lang3.StringEscapeUtils)는 더 이상 사용되지 않으며 org.apache.commons.text.StringEscapeUtils
jcarter

-4

다음은 나를 위해 작동하는 것 같습니다.

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

나는 char이 String, Strings 및 chars의 기본 변수 유형이기 때문에 결합 될 수 있다고 생각합니다 (적어도 이클립스 컴파일러는 불평하지 않는 것 같습니다).


1
char이 String <-에 대한 기본 변수 유형이기 때문에 가정이 잘못되었습니다. 그 문제를 위해 int와 같은 다른 유형에서도 작동합니다. String x = "Some text"+ 33 + "More text";
Najeeb

-6

이스케이프 '하거나 "문자열에서 다음 코드를 사용할 수 있습니다.

String text = ...

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

질문은 소스 코드의 문자열 리터럴에 대해 물었습니다. 죄송하지만 다시 시도하세요.
michaelb958--GoFundMonica
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.