Trong Java, có cách nào để viết một chuỗi ký tự mà không cần phải thoát khỏi dấu ngoặc kép?


111

Giả sử bạn có một chuỗi ký tự với rất nhiều dấu ngoặc kép bên trong nó. Bạn có thể thoát khỏi tất cả, nhưng đó là một nỗi đau và khó đọc.

Trong một số ngôn ngữ, bạn chỉ có thể làm điều này:

foo = '"Hello, World"';

Trong Java, tuy nhiên, ''được sử dụng cho chars, vì vậy bạn không thể sử dụng nó cho Strings theo cách này. Một số ngôn ngữ có cú pháp để giải quyết vấn đề này. Ví dụ: trong python, bạn có thể làm điều này:

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

Java có gì tương tự không?



Câu trả lời này cho thấy cách dán các chuỗi thoát nhiều dòng trong Eclispe.
Jeff Axelrod

2
Cập nhật 2018: chuỗi ký tự thô cho Java có thể sắp ra mắt. Xem câu trả lời của tôi bên dưới
VonC

nhập khẩu jackson ObjectMapper sau đó System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv

cập nhật Q4 2018: chuỗi thô vẫn chưa xuất hiện. Xem câu trả lời cập nhật của tôi .
VonC

Câu trả lời:


74

Câu trả lời là không, và bằng chứng nằm trong Đặc tả ngôn ngữ Java :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Như bạn có thể thấy, một StringLiteralcó thể bị ràng buộc bởi "và không thể chứa ký tự đặc biệt nếu không có lối thoát ..

Một mặt lưu ý: bạn có thể nhúng Groovy bên trong dự án của bạn, điều này sẽ mở rộng cú pháp của Java cho phép bạn sử dụng '''multi line string ''', ' "string with single quotes" 'và cũng có thể "string with ${variable}".


141

Không, và tôi luôn khó chịu vì thiếu các cú pháp chuỗi-ký tự khác nhau trong Java.

Đây là một mẹo tôi đã sử dụng thường xuyên:

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

Tôi chủ yếu chỉ làm một cái gì đó như vậy cho một trường tĩnh. Vì nó tĩnh nên mã thay thế chuỗi được gọi một lần, khi khởi tạo lớp. Vì vậy, hình phạt hiệu suất thời gian chạy thực tế không tồn tại và nó làm cho mã dễ đọc hơn đáng kể.


bạn sẽ không cần phải sử dụng ReplaceAll?
Landon Kuhn

10
@ landon9720 Không, .replace thay thế tất cả các lần xuất hiện của một ký tự / chuỗi ký tự bằng ký tự / chuỗi ký tự khác. .replaceAll đều sử dụng regex.
abelito

Vì tò mò, bạn có biết liệu trình biên dịch java có đơn giản hóa điều này khi biên dịch không?
ug_

2
Không, tôi không nghĩ rằng trình biên dịch sẽ đơn giản hóa điều này. Nhưng nó không thực sự quan trọng. Đó là một lệnh gọi rất rẻ và nếu tôi chỉ thực hiện việc này cho các chuỗi cuối cùng tĩnh, chi phí sẽ chỉ phát sinh một lần khi tải lớp. Đó là một mức giá tôi thường sẵn sàng trả cho đẹp hơn tìm code :)
benjismith

3
Vậy còn "\" trong chuỗi của tôi thì sao?
Anderson

10

Cập nhật vào tháng 12 năm 2018 (12 tháng sau):

Các ký tự chuỗi thô (nằm trong danh sách màu hổ phách ) sẽ không đạt đến JDK 12.
Xem các lời chỉ trích tại đây .


Có thể có trong một phiên bản Java trong tương lai (10 trở lên).

Xem JEPS 8196004 từ tháng 1 năm 2018: ( "JEP" là "Chương trình nâng cao JDK" )

Dự thảo JEP: Chữ viết chuỗi thô

Thêm một loại ký tự mới, một ký tự chuỗi thô, vào ngôn ngữ lập trình Java.
Giống như ký tự chuỗi truyền thống, một ký tự chuỗi thô tạo ra một Chuỗi, nhưng không diễn giải thoát chuỗi và có thể kéo dài nhiều dòng mã nguồn .

Vì vậy, thay vì:

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

Bạn có thể gõ:

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

Khéo léo!

Nhưng nó vẫn chỉ là một bản nháp : nó sẽ cần được đăng, gửi, trở thành ứng cử viên và được tài trợ, trước khi hoàn thành và đưa vào JDK tiếp theo.


5

Câu trả lời đơn giản: Không.

Đối với các chuỗi dài hơn phải được thoát, tôi thường đọc chúng từ một số tài nguyên bên ngoài.


4

bạn cũng có thể sử dụng StringEscapeUtils từ các dấu phẩy của apache

CẬP NHẬT : Nếu ai đó quan tâm đến một số ví dụ, đây là một liên kết hữu ích: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils


2
Bạn có thể vui lòng thêm một ví dụ có thể dựa trên câu hỏi minh họa cách thực hiện nó cho vấn đề này không?
Kéo dài

3
Nó được coi là không tối ưu nếu chỉ tham khảo một nguồn khác có thể trả lời câu hỏi. Vui lòng xem xét tóm tắt trang được liên kết với một ví dụ phù hợp với câu hỏi.
Kéo dài

Tôi đã xem qua và không nghĩ rằng một trong hai thực sự trả lời câu hỏi. Các đầu vào cho các phương thức tĩnh là Strings, vì vậy không có cách nào để có một giá trị được định dạng độc đáo trong mã của bạn. Có lẽ bạn có thể sử dụng các phương pháp này để đọc từ tệp thành tệp String, nhưng tôi không nghĩ đó là câu hỏi ở đây.
Tom Harrison

Các lớp liên kết (org.apache.commons.lang3.StringEscapeUtils) đã phản đối và thay thế bằng org.apache.commons.text.StringEscapeUtils
jcarter

-4

Những điều sau đây dường như hiệu quả với tôi:

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

Tôi nghĩ vì char là kiểu biến nguyên thủy cho Chuỗi, các chuỗi và ký tự có thể được kết hợp (ít nhất là trình biên dịch eclipse dường như không phàn nàn).


1
Tôi nghĩ vì char là kiểu biến nguyên thủy cho Chuỗi <- Giả định của bạn là không chính xác. Đối với vấn đề đó, nó cũng sẽ hoạt động với một kiểu khác, chẳng hạn như int, chẳng hạn như sau: String x = "Some text" + 33 + "More text";
Najeeb

-6

Nếu bạn muốn thoát 'hoặc "trong chuỗi của mình, bạn có thể sử dụng mã sau:

String text = ...

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

Câu hỏi đặt ra về chuỗi ký tự trong mã nguồn. Xin lỗi, hãy thử lại.
michaelb958 - GoFundMonica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.