Câu trả lời:
Kể từ Java 1.5, có :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
đó sẽ trở lại MicE
. Bạn would't hy vọng nó sẽ trở lại MICE
bởi vì bạn đã không áp dụng toUpperCase()
vào ic
. Trong ví dụ của tôi quote()
cũng được áp dụng trên .*
insertet replaceAll()
. Bạn phải làm một cái gì đó khác, có lẽ .replaceAll("*","\\E.*\\Q")
sẽ làm việc, nhưng đó là phản trực giác.
*.wav
thành mô hình regex \*\.wav
, và thay thế All sẽ biến nó thành \.*\.wav
, nghĩa là nó sẽ biến thành khớp các tệp có tên bao gồm một số lượng thời gian tùy ý theo sau .wav
. Bạn rất có thể cần phải làm replaceAll("\\*", ".*")
như vậy nếu họ đã đi với việc triển khai mỏng manh hơn dựa vào việc nhận ra tất cả các trình duyệt regex hoạt động có thể có và thoát chúng riêng lẻ ... điều đó có dễ dàng hơn nhiều không?
Sự khác biệt giữa Pattern.quote
và Matcher.quoteReplacement
không rõ ràng với tôi trước khi tôi thấy ví dụ sau
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
thay thế các ký tự đặc biệt trong chuỗi tìm kiếm regex, như. | + () V.v. và Matcher.quoteReplacement
thay thế các ký tự đặc biệt trong chuỗi thay thế, như \ 1 cho các phản hồi.
quoteReplacement
chỉ quan tâm đến hai biểu tượng $
và \
ví dụ có thể được sử dụng trong các chuỗi thay thế như phản hồi $1
hoặc \1
. Do đó, nó không được sử dụng để thoát / trích dẫn một biểu thức chính quy.
$Group$
bằng T$UYO$HI
. Các $
biểu tượng là đặc biệt cả về mô hình và trong việc thay thế:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Có thể quá muộn để trả lời, nhưng bạn cũng có thể sử dụng Pattern.LITERAL
, sẽ bỏ qua tất cả các ký tự đặc biệt trong khi định dạng:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Tôi nghĩ những gì bạn đang theo đuổi là \Q$5\E
. Cũng thấyPattern.quote(s)
giới thiệu trong Java5.
Xem mẫu javadoc để biết chi tiết.
Trước hết, nếu
nó sẽ không đặt 1 ở cuối Nó sẽ xem xét biểu thức tìm kiếm cho nhóm phù hợp đầu tiên và THAT phụ. Đó là $ 1, $ 2 hoặc $ 3 có nghĩa là gì trong văn bản thay thế: nhóm phù hợp từ mẫu tìm kiếm.
Tôi thường xuyên cắm các chuỗi văn bản dài vào các tệp .properations, sau đó tạo các chủ đề và nội dung email từ các tệp đó. Thật vậy, điều này dường như là cách mặc định để thực hiện i18n trong Spring Framework. Tôi đặt các thẻ XML, với tư cách là các trình giữ chỗ, vào các chuỗi và tôi sử dụng thay thế All () để thay thế các thẻ XML bằng các giá trị khi chạy.
Tôi gặp phải một vấn đề trong đó người dùng nhập số đô la và xu, với ký hiệu đô la. thayTất cả () nghẹn ngào với nó, với phần sau hiển thị trong một chuỗi:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
Trong trường hợp này, người dùng đã nhập "$ 3" ở đâu đó trong đầu vào của họ và thay thế All () đã tìm kiếm trong biểu thức tìm kiếm cho nhóm khớp thứ ba, không tìm thấy và bị loại.
Được:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
thay thế
msg = msg.replaceAll("<userInput \\/>", userInput);
với
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
Đã giải quyết vấn đề. Người dùng có thể đặt bất kỳ loại ký tự nào, kể cả ký hiệu đô la, mà không có vấn đề. Nó hành xử chính xác theo cách bạn mong đợi.
Để có mẫu được bảo vệ, bạn có thể thay thế tất cả các ký hiệu bằng "\\\\", ngoại trừ chữ số và chữ cái. Và sau đó, bạn có thể đặt vào mẫu được bảo vệ đó các ký hiệu đặc biệt của mình để làm cho mẫu này hoạt động không giống như văn bản trích dẫn ngu ngốc, nhưng thực sự giống như một patten, nhưng là của riêng bạn. Không có biểu tượng người dùng đặc biệt.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote ("blabla") hoạt động độc đáo.
Pattern.quote () hoạt động độc đáo. Nó kèm theo câu với các ký tự " \ Q " và " \ E " và nếu nó thoát "\ Q" và "\ E". Tuy nhiên, nếu bạn cần thực hiện thoát biểu thức chính quy thực (hoặc thoát tùy chỉnh), bạn có thể sử dụng mã này:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Phương thức này trả về: Một số / \ s / wText * / \, **
Mã ví dụ và kiểm tra:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Biểu tượng ^ (Phủ định) được sử dụng để khớp với thứ không thuộc nhóm nhân vật.
Đây là liên kết đến Biểu thức chính quy
Dưới đây là thông tin hình ảnh về phủ định:
\Q
và\E
. Điều này có thể dẫn đến kết quả không mong muốn, ví dụPattern.quote("*.wav").replaceAll("*",".*")
sẽ dẫn đến\Q.*.wav\E
và không.*\.wav
, như bạn có thể mong đợi.