Yanıtlar:
Java 1.5'ten beri , evet :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
geri döner MicE
. Bunu dönmek bekliyoruz would't MICE
sen uygulanmadığı için toUpperCase()
üzerinde ic
. Benim örnekte quote()
uygulanır .*
tarafından insertet replaceAll()
de. Başka bir şey yapmalısınız, belki .replaceAll("*","\\E.*\\Q")
işe yarayacaktı, ama bu mantıksız.
*.wav
normal ifade düzenine dönüşür \*\.wav
ve replaceAll bunu dönüştürür \.*\.wav
, yani adı gelişigüzel sayıda noktadan sonra gelen dosyaları eşleştirir .wav
. Muhtemelen replaceAll("\\*", ".*")
tüm aktif regex karakterlerini tanımaya ve onlardan tek tek kaçmaya dayanan daha kırılgan bir uygulama ile gitmiş olsalardı, bu çok daha kolay olurdu mı?
Aşağıdaki örneği görmeden önce Pattern.quote
ve arasındaki fark Matcher.quoteReplacement
net değildi
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
regex arama dizelerindeki. | + () Vb. Gibi Matcher.quoteReplacement
özel karakterlerin yerini alır ve yedek başvurular için \ 1 gibi değiştirme dizelerinde özel karakterlerin yerini alır.
quoteReplacement
yalnızca iki simgeyi önemser $
ve \
örneğin değiştirme dizelerinde backreferences $1
ya da olarak kullanılabilir \1
. Bu nedenle bir normal ifadeden kaçmak / alıntı yapmak için kullanılmamalıdır.
$Group$
ile T$UYO$HI
. $
Sembol desende ve değiştirme hem de özel:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Bence peşinde olduğun şey \Q$5\E
. Ayrıca bkz Pattern.quote(s)
. Java5'te tanıtıldı.
Ayrıntılar için bkz. Pattern javadoc.
İlk önce, eğer
sonuna 1 koymaz. İlk eşleşen grup ve alt THAT için arama normal ifadesine bakacaktır. Değiştirme metninde $ 1, $ 2 veya $ 3 budur: arama modelindeki eşleşen gruplar.
Sık sık uzun metin dizelerini .properties dosyalarına bağlarım, sonra bunlardan e-posta konuları ve gövdeleri oluştururum. Aslında, bu Spring Framework'te i18n yapmanın varsayılan yolu gibi görünüyor. Yer tutucuları olarak XML etiketlerini dizelere koydum ve XML etiketlerini çalışma zamanında değerlerle değiştirmek için replaceAll () kullanıyorum.
Bir kullanıcının dolar işareti olan bir dolar ve sent rakamı girdiği bir sorunla karşılaştım. replaceAll (), aşağıda bir stracktrace içinde görünecek şekilde boğuldu:
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)
Bu durumda, kullanıcı girdilerinde bir yere "$ 3" girmiş ve replaceAll () üçüncü eşleşen grubun arama regex'ine gitti, bir tane bulamadı ve puked.
Verilen:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
yerine
msg = msg.replaceAll("<userInput \\/>", userInput);
ile
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
sorunu çözdü. Kullanıcı dolar işareti de dahil olmak üzere her türlü karakteri sorunsuzca girebilir. Tam olarak beklediğiniz gibi davrandı.
Korumalı desene sahip olmak için, rakamlar ve harfler hariç tüm sembolleri "\\\\" ile değiştirebilirsiniz. Ve bundan sonra, bu kalıbın aptalca alıntılanmış metin gibi değil, gerçekten bir patten gibi, ama sizinki gibi çalışmasını sağlamak için bu korumalı deseni koyabilirsiniz. Kullanıcıya özel semboller olmadan.
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") iyi çalışıyor.
Pattern.quote () iyi çalışıyor. Cümleyi " \ Q " ve " \ E " karakterleriyle içine alır ve eğer "\ Q" ve "\ E" 'den kaçarsa. Ancak, kaçan (veya özel kaçan) gerçek bir düzenli ifade yapmanız gerekiyorsa, bu kodu kullanabilirsiniz:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Bu yöntem şunu döndürür: Bazı / \ s / wText * / \, **
Örnek kodlar ve testler:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
^ (Olumsuzlama) sembolü, karakter grubunda olmayan bir şeyi eşleştirmek için kullanılır.
Bu bağlantı Düzenli İfadelerin
İşte olumsuzluk hakkında resim bilgisi:
\Q
ve\E
. Örnek için bu, beklenmedik sonuçlara yol açabilirPattern.quote("*.wav").replaceAll("*",".*")
neden olur\Q.*.wav\E
ve.*\.wav
Tahmin edebileceğiniz gibi.