2013-01-31 12 views
18

मैं है निम्न वर्णों कि मैं चाहती हूं "अवैध" पर विचार किया जाना शामिल है वापस जाने के लिए:जावा समारोह यदि स्ट्रिंग अवैध अक्षर

~, #, @, *, +, %, {, }, <, >, [, ], |, , , \, _, ^

मैं एक विधि है कि एक स्ट्रिंग निरीक्षण करता है और निर्धारित करता है (true/false) लिखने के लिए चाहते हैं, तो यह है कि स्ट्रिंग इन अवैध शामिल हैं:

public boolean containsIllegals(String toExamine) { 
    return toExamine.matches("^.*[~#@*+%{}<>[]|\"\\_^].*$"); 
} 

हालांकि, एक सरल matches(...) जांच इस बात के लिए संभव नहीं है। मुझे स्ट्रिंग में प्रत्येक चरित्र को स्कैन करने की विधि चाहिए और सुनिश्चित करें कि यह इन वर्णों में से एक नहीं है। बेशक, मैं कुछ कर सकते हैं भयानक की तरह:

public boolean containsIllegals(String toExamine) { 
    for(int i = 0; i < toExamine.length(); i++) { 
     char c = toExamine.charAt(i); 

     if(c == '~') 
      return true; 
     else if(c == '#') 
      return true; 

     // etc... 
    } 
} 

वहाँ एक और अधिक सुरुचिपूर्ण/इस पूरा करने की कारगर तरीका है?

+5

'मैचों 'का उपयोग करना क्यों संभव नहीं है? –

+0

क्योंकि यह अच्छा नहीं है! – thang

उत्तर

25

आप यहाँ Pattern और Matcher वर्ग का उपयोग कर सकते हैं। आप सभी फ़िल्टर किए गए चरित्र को एक वर्ण वर्ग में रख सकते हैं, और यह जांचने के लिए कि आपका पैटर्न स्ट्रिंग में उपलब्ध है या नहीं, Matcher#find() विधि का उपयोग करें।

आप इस तरह यह कर सकते हैं: -

public boolean containsIllegals(String toExamine) { 
    Pattern pattern = Pattern.compile("[~#@*+%{}<>\\[\\]|\"\\_^]"); 
    Matcher matcher = pattern.matcher(toExamine); 
    return matcher.find(); 
} 

find() विधि सच वापस आ जाएगी, अगर दिए गए पैटर्न स्ट्रिंग में पाया जाता है, एक बार भी।


एक अन्य तरीका जिसे अभी तक इंगित नहीं किया गया है String#split(regex) का उपयोग कर रहा है। हम दिए गए पैटर्न पर स्ट्रिंग को विभाजित कर सकते हैं, और सरणी की लंबाई की जांच कर सकते हैं। यदि लंबाई 1 है, तो पैटर्न स्ट्रिंग में नहीं था।

public boolean containsIllegals(String toExamine) { 
    String[] arr = toExamine.split("[~#@*+%{}<>\\[\\]|\"\\_^]", 2); 
    return arr.length > 1; 
} 

तो arr.length > 1, कि स्ट्रिंग पैटर्न में चरित्र में से एक, यही वजह है कि यह splitted था मतलब है। मैंने limit = 2 को split पर दूसरे पैरामीटर के रूप में पारित किया है, क्योंकि हम केवल एक विभाजन के साथ ठीक हैं।

+0

स्वच्छ और सर्वोत्तम समझाया गया। – IAmYourFaja

+0

जो लोग अनुसरण करते हैं और विवरण में भी फंस जाते हैं, ध्यान दें कि "matcher.find" के साथ आप ब्रैकेट के अंदर केवल सामग्री के साथ छोटी नियमित अभिव्यक्ति का उपयोग करते हैं, लेकिन "matcher.matches" के साथ आप लंबी अभिव्यक्ति का उपयोग करेंगे। दोनों तकनीकों ने मेरे यूनिट परीक्षणों को तब तक पारित किया जब तक प्रत्येक के लिए सही नियमित अभिव्यक्ति का उपयोग नहीं किया जाता। – Ted

+0

दूसरी विधि बहुत अच्छी है! अच्छा –

10

मैं विधि की जरूरत स्ट्रिंग

के प्रत्येक वर्ण को स्कैन करने के लिए आप इसे चरित्र-दर-चरित्र क्या करना चाहिए, तो regexp शायद जाने के लिए एक अच्छा तरीका नहीं है। हालांकि, अपने "काली सूची" पर सभी पात्रों के बाद से कोड 128 की तुलना में कम है, तो आप एक छोटे से boolean सरणी के साथ यह कर सकते हैं:

static final boolean blacklist[] = new boolean[128]; 

static { 
    // Unassigned elements of the array are set to false 
    blacklist[(int)'~'] = true; 
    blacklist[(int)'#'] = true; 
    blacklist[(int)'@'] = true; 
    blacklist[(int)'*'] = true; 
    blacklist[(int)'+'] = true; 
    ... 
} 

static isBad(char ch) { 
    return (ch < 128) && blacklist[(int)ch]; 
} 
+0

यदि मुझे गलत नहीं है, तो अनियंत्रित बूलियन जावा में झूठे हो जाते हैं, है ना? – 11684

+0

@ 11684 सही - 'बुलियन' सरणी के तत्व प्रारंभ में 'झूठी' हैं। – dasblinkenlight

+1

शायद यह उत्तर का हिस्सा हो सकता है, इसलिए प्रोग्रामर इसे भी समझ सकते हैं? – 11684

7

यदि आप एक मैचर का उपयोग नहीं कर सकते हैं, तो आप ऐसा कुछ कर सकते हैं, जो बयान या बाइट सरणी के अलग-अलग समूह के मुकाबले क्लीनर है।

for(int i = 0; i < toExamine.length(); i++) { 
    char c = toExamine.charAt(i); 
    if("~#@*+%{}<>[]|\"_^".contains(c)){ 
     return true; 
    } 
} 
5

सब काली सूची में डाल वर्ण युक्त एक चरित्र वर्ग का निषेध का प्रयास करें:

public boolean containsIllegals(String toExamine) { 
    return toExamine.matches("[^~#@*+%{}<>\\[\\]|\"\\_^]*"); 
} 

यह true वापस आ जाएगी अगर स्ट्रिंग अवैध है (अपने मूल कार्य उस मामले में false वापस जाने के लिए लग रहा था)।

देखभाल ^ केवल उद्घाटन ब्रैकेट [ के दाईं ओर चरित्र वर्ग को अस्वीकार करता है। ध्यान दें कि String.matches() में आपको एंकर ^ और $ की आवश्यकता नहीं है क्योंकि यह स्वचालित रूप से संपूर्ण स्ट्रिंग से मेल खाता है।

2

ऐसा करने String.replaceAll पद्धति पर भरोसा करने के लिए किया जाएगा का एक बहुत कॉम्पैक्ट रास्ता:

public boolean containsIllegal(final String toExamine) { 
    return toExamine.length() != toExamine.replaceAll(
      "[~#@*+%{}<>\\[\\]|\"\\_^]", "").length(); 
} 
6

टाल के लिए एक निरंतर हर सत्यापन में regex पुनः संकलित करें का प्रयोग करें।

private static final Pattern INVALID_CHARS_PATTERN = 
           Pattern.compile("^.*[~#@*+%{}<>\\[\\]|\"\\_].*$"); 

और करने के लिए अपने कोड बदलने के लिए:

public boolean containsIllegals(String toExamine) { 
    return INVALID_CHARS_PATTERN.matcher(toExamine).matches(); 
} 

यह Regex के साथ सबसे कारगर तरीका है।

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