सबसे पहले, मुझे वास्तव में सवाल पसंद है। अब, आप जो चाहते हैं उसे एक replaceAll
के साथ नहीं किया जा सका, क्योंकि इसके लिए, हमें negative look-behind
की आवश्यकता होती है जिसमें परिवर्तनीय लंबाई होती है, जिसकी अनुमति नहीं है। अगर इसकी अनुमति थी, तो यह मुश्किल नहीं होता।
वैसे भी, चूंकि एकल replaceAll
यहां कोई विकल्प नहीं है, तो आप यहां एक छोटी हैक का उपयोग कर सकते हैं। entity reference
के पहले semi-colon
को पहले वर्णित करने की तरह, कुछ वर्ण अनुक्रम के साथ, जो आप सुनिश्चित हैं, शेष स्ट्रिंग में XXX
या कुछ भी नहीं होगा। मुझे पता है कि यह सही नहीं है, लेकिन आप निश्चित रूप से इसकी मदद नहीं कर सकते हैं।
तो, यहाँ तुम क्या करने की कोशिश कर सकते हैं:
String str = "a;b&c &";
str = str.replaceAll("(&\\w+);", "$1XXX")
.replaceAll("&(?!\\w+?XXX)|[^\\w&]", "")
.replaceAll("(&\\w+)XXX", "$1;");
System.out.println(str);
स्पष्टीकरण:
- पहले replaceAll,
&XXX
साथ &
तरह पैटर्न, या पिछले ;
के लिए प्रतिस्थापित किसी अन्य अनुक्रम बदल देता है।
- दूसरा प्रतिस्थापन सभी,
&
को \\w+XXX
, या non-word, non &
वर्ण के बाद बदल देता है। यह सभी &'s
को प्रतिस्थापित करेगा जो &
पैटर्न का हिस्सा नहीं हैं। इसके अलावा, किसी अन्य गैर-शब्द चरित्र को भी बदल देता है।
- तीसरे replaceAll, फिर से बदल देता है
;
साथ XXX
, वापस &
&XXX
और से बनाने के लिए यह आसान समझने के लिए बनाने के लिए, यदि आप इसके बजाय Pattern
और Matcher
कक्षाओं का उपयोग कर सकते हैं और मैं हमेशा पसंद करेंगे प्रतिस्थापन मानदंड जटिल होने पर उनका उपयोग करने के लिए।
String str = "a;b&c &";
Pattern pattern = Pattern.compile("&\\w+;|[^\\w]");
Matcher matcher = pattern.matcher(str);
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
String match = matcher.group();
if (!match.matches("&\\w+;")) {
matcher.appendReplacement(sb, "");
} else {
matcher.appendReplacement(sb, match);
}
}
matcher.appendTail(sb);
System.out.println(sb.toString());
यह एक @ एरिक के कोड के समान है, लेकिन यह एक सामान्यीकरण है। वह केवल &
के लिए काम करेगा यदि इसमें NullPointerException
को निकालने के लिए इसे बेहतर किया गया है।
स्रोत
2013-02-14 18:46:37
+1 वास्तव में अच्छा सवाल है। –