जांचें कि क्या एक स्ट्रिंग में 10 वर्ण हैं


107

मैं C # का उपयोग कर रहा हूं और मैं यह जांचना चाहता हूं कि क्या किसी स्ट्रिंग में दस वर्णों में से एक, *, &, # आदि हैं।

सबसे अच्छा तरीका क्या है?


1
क्या आप यह देखना चाहते हैं कि उनमें से कोई भी पात्र है, या यदि उसमें उन पात्रों में से "एक" (यानी: बिल्कुल एक) है, और केवल एक है?
रीड कोपसे

जवाबों:


210

मेरे विचार में निम्नलिखित सबसे सरल विधि होगी:

var match = str.IndexOfAny(new char[] { '*', '&', '#' }) != -1

या पढ़ने के लिए संभव रूप में आसान है:

var match = str.IndexOfAny("*&#".ToCharArray()) != -1

आवश्यक संदर्भ और प्रदर्शन के आधार पर, आप वर्ण सरणी को कैश करना चाहते हैं या नहीं कर सकते हैं।


जब वर्ण सरणी को तत्काल किया जाता है, तो प्रकार छोड़ा जा सकता है और यह अनुमान लगाया जाएगा।
पालक

40

जैसा कि दूसरों ने कहा है, IndexOfAny का उपयोग करें। हालाँकि, मैं इसे इस तरह इस्तेमाल करूँगा:

private static readonly char[] Punctuation = "*&#...".ToCharArray();

public static bool ContainsPunctuation(string text)
{
    return text.IndexOfAny(Punctuation) >= 0;
}

इस तरह आप प्रत्येक कॉल पर एक नया एरे बनाते हुए समाप्त नहीं होते हैं। स्ट्रिंग भी चरित्र शाब्दिक, IMO की एक श्रृंखला की तुलना में स्कैन करने के लिए आसान है।

बेशक, यदि आप केवल एक बार इसका उपयोग करने जा रहे हैं, तो व्यर्थ निर्माण एक समस्या नहीं है, आप या तो उपयोग कर सकते हैं:

private const string Punctuation = "*&#...";

public static bool ContainsPunctuation(string text)
{
    return text.IndexOfAny(Punctuation.ToCharArray()) >= 0;
}

या

public static bool ContainsPunctuation(string text)
{
    return text.IndexOfAny("*&#...".ToCharArray()) >= 0;
}

यह वास्तव में निर्भर करता है, जिस पर आप अधिक पठनीय लगते हैं, चाहे आप विराम चिह्नों का उपयोग कहीं और करना चाहते हों, और कितनी बार विधि कहा जाना है।


संपादित करें: यहां यह पता लगाने के लिए रीड कोपसे की विधि का एक विकल्प है कि क्या एक स्ट्रिंग में बिल्कुल पात्रों में से एक है।

private static readonly HashSet<char> Punctuation = new HashSet<char>("*&#...");

public static bool ContainsOnePunctuationMark(string text)
{
    bool seenOne = false;

    foreach (char c in text)
    {
        // TODO: Experiment to see whether HashSet is really faster than
        // Array.Contains. If all the punctuation is ASCII, there are other
        // alternatives...
        if (Punctuation.Contains(c))
        {
            if (seenOne)
            {
                return false; // This is the second punctuation character
            }
            seenOne = true;
        }
    }
    return seenOne;
}

अगर मुझे लगता है कि प्रदर्शन की समस्या है, तो यह चार सरणी की कैशिंग के लायक है, लेकिन फिर यह संदर्भ के आधार पर इसके लायक नहीं हो सकता है।
नोल्डोरिन

1
हां, यदि आप इसे केवल एक विधि में उपयोग कर रहे हैं जो एक बार निष्पादित होने जा रहा है तो यह इसके लायक नहीं हो सकता है। हालांकि, मुझे लगता है कि यह पठनीयता के साथ-साथ प्रदर्शन में सुधार करता है। ToCharArrayयदि आवश्यक हो, तो आप फॉर्म "इनलाइन" का उपयोग कर सकते हैं ।
जॉन स्कीट

1
@ डकॉन: सेट कितना बड़ा है? बहुत, बहुत छोटे सेटों के लिए, मैं Array.Contains के तेज़ होने की उम्मीद करूँगा। बड़े सेटों के लिए, हाशसेट को मीलों तक जीतने की संभावना है।
जॉन स्कीट

5

यदि आप केवल यह देखना चाहते हैं कि क्या इसमें कोई चरित्र है या नहीं, तो मैं आपको string.IndexOfAny का उपयोग करने की सलाह दूंगा, जैसा कि अन्यत्र सुझाया गया है।

यदि आप यह सत्यापित करना चाहते हैं कि स्ट्रिंग में ठीक दस में से एक अक्षर है, और केवल एक है, तो यह थोड़ा और अधिक जटिल हो जाता है। मेरा मानना ​​है कि सबसे तेज़ तरीका एक अंतर के खिलाफ जांचना होगा, फिर डुप्लिकेट के लिए जांच करें।

private static char[] characters = new char [] { '*','&',... };

public static bool ContainsOneCharacter(string text)
{
    var intersection = text.Intersect(characters).ToList();
    if( intersection.Count != 1)
        return false; // Make sure there is only one character in the text

    // Get a count of all of the one found character
    if (1 == text.Count(t => t == intersection[0]) )
        return true;

    return false;
}

हाँ - मुझे लगता है कि एक एकल लूप शायद इस मामले में तेज है, विशेष रूप से विराम चिह्न के छोटे सेट के साथ। मुझे यह देखने के लिए उत्सुक होना चाहिए कि यह बड़े स्ट्रिंग्स के साथ परीक्षण करना है जो वास्तव में तेज़ है।
रीड कोपसे

1
मुझे लगता है कि दो स्ट्रिंग्स के चौराहे को खोजने के लिए चरित्र द्वारा चरित्र को वैसे भी जाना है, इसलिए मैं यह नहीं देख सकता कि यह कैसे तेज होगा ... और मेरे सुझाए गए मार्ग में न केवल एक पास का उपयोग होता है, बल्कि यह भी है एक "जल्दी बाहर" का विकल्प। कल्पना कीजिए कि यदि पाठ एक लाख वर्ण लंबा है, लेकिन पहले दो दोनों "*" हैं :)
जॉन स्कीट


1
var specialChars = new[] {'\\', '/', ':', '*', '<', '>', '|', '#', '{', '}', '%', '~', '&'};

foreach (var specialChar in specialChars.Where(str.Contains))
{
    Console.Write(string.Format("string must not contain {0}", specialChar));
}

0

आप सभी को धन्यवाद! (और मुख्य रूप से जॉन!): इससे मुझे यह लिखने की अनुमति मिली:

    private static readonly char[] Punctuation = "$€£".ToCharArray();

    public static bool IsPrice(this string text)
    {
        return text.IndexOfAny(Punctuation) >= 0;
    }

जैसा कि मैं यह पता लगाने के लिए एक अच्छा तरीका खोज रहा था कि क्या एक निश्चित स्ट्रिंग वास्तव में एक मूल्य या एक वाक्य था, जैसे 'बहुत कम प्रदर्शित करने के लिए'।


2
मुझे पता है कि यह पुराना है, लेकिन यह स्पष्ट है कि यह मुद्राओं से मेल खाने का एक अच्छा तरीका नहीं है ... यदि आपके पास कोई "के $ हा" लिखता है तो यह एक कीमत के रूप में मेल खाता है ... इसके बजाय एक उचित तरीके का संदर्भ लें मुद्रा को यहां परिभाषित करें: stackoverflow.com/questions/7214513/…
mcse3010
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.