2013-02-14 9 views
9

मैं जब यह है के अलावा सभी गैर शब्द चरित्र की एक स्ट्रिंग साफ करने के लिए कोशिश कर रहा हूँ के अलावा सभी गैर शब्द चार निकालें & यानी पैटर्न की तरह &[\w]+;अगर & या ' पैटर्न

उदाहरण के लिए हो सकता है:

abc; => abc 
abc & => abc & 
abc& => abc 

यदि मैं string.replaceAll("\W","") का उपयोग करता हूं तो यह ; और '&' को दूसरे उदाहरण से भी हटा देता है जो मैं नहीं चाहता हूं।

इस समस्या में नकारात्मक दिखने का उपयोग कर त्वरित समाधान रेगेक्स पैटर्न दे सकता है?

+1

+1 वास्तव में अच्छा सवाल है। –

उत्तर

2

सबसे पहले, मुझे वास्तव में सवाल पसंद है। अब, आप जो चाहते हैं उसे एक 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, &ampXXX साथ & तरह पैटर्न, या पिछले ; के लिए प्रतिस्थापित किसी अन्य अनुक्रम बदल देता है।
  • दूसरा प्रतिस्थापन सभी, & को \\w+XXX, या non-word, non & वर्ण के बाद बदल देता है। यह सभी &'s को प्रतिस्थापित करेगा जो & पैटर्न का हिस्सा नहीं हैं। इसके अलावा, किसी अन्य गैर-शब्द चरित्र को भी बदल देता है।
  • तीसरे replaceAll, फिर से बदल देता है ; साथ XXX, वापस &&ampXXX

और से बनाने के लिए यह आसान समझने के लिए बनाने के लिए, यदि आप इसके बजाय 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 को निकालने के लिए इसे बेहतर किया गया है।

+0

अच्छा जवाब, हालांकि शुरुआत में मैं एक और कॉम्पैक्ट समाधान के लिए चाहता था। – dreamcrash

+0

@dreamcrash। यह थोड़ा कॉम्पैक्ट हो सकता था, जावा रेगेक्स में परिवर्तनीय लंबाई लुक-बैक की अनुमति थी। इस मामले में प्रतिस्थापन सीधे जैसा होगा: 'str.replaceAll (" (?

+0

@dreamcrash। AFAIK, कुछ रेगेक्स इंजन वैरिएबल लम्बाई लुक-बैक की अनुमति देते हैं, लेकिन मुझे वास्तव में याद नहीं है कि वे कौन हैं। –

0

मेरा सुझाव है कि आप इस तरह एक नकारात्मक अग्रदर्शी का उपयोग करें:

string.replace(/&(?!\w+;)/ig, ''); 

कौन सा सब & अर्धविराम के साथ समाप्त एक शब्द पात्रों द्वारा पीछा नहीं बदल देता है।

संपादित करें (जावा):

string.replaceAll("/&(?!\w+;)/i", ''); 
+0

हाहा, मैंने "जावास्क्रिप्ट" पढ़ा ... इसलिए मेरे संपादन के करीब कुछ जावा में काम करना चाहिए। – migg

2

मैं सुनिश्चित नहीं हूं कि आप इस एक सरल String.replaceAll उपयोग कर सकते हैं। आपको मैचों के माध्यम से लूप करने के लिए शायद Pattern और Matcher का उपयोग करना चाहिए, प्रभावी ढंग से मैन्युअल खोज करना और प्रतिस्थापित करना चाहिए। निम्नलिखित कोड की तरह कुछ चाल करना चाहिए।

public String replaceString(String origString) { 
    Pattern pattern = Pattern.compile("&(\w+);|[^\w]"); 
    Matcher matcher = pattern.matcher(origString); 
    StringBuffer sb = new StringBuffer(); 
    while (matcher.find()) { 
     if (matcher.group().startsWith("&") && !matcher.group(1).equals("amp")) { 
      matcher.appendReplacement(sb, matcher.group()); 
     } else { 
      matcher.appendReplacement(sb, ""); 
     } 
    } 
    matcher.appendTail(sb); 
    return sb.toString(); 
} 
+0

+1 समाधान के लिए धन्यवाद! – Watt

संबंधित मुद्दे