सब कुछ करने से पहले सब कुछ प्राप्त करें


124

मैं एक स्ट्रिंग में चरित्र से पहले सब कुछ पाने के लिए सबसे अच्छा तरीका जानने की कोशिश कर रहा हूं। कुछ उदाहरण तार नीचे हैं। पहले स्ट्रिंग की लंबाई - भिन्न होती है और कोई भी लंबाई हो सकती है

223232-1.jpg
443-2.jpg
34443553-5.jpg

इसलिए मुझे उस मूल्य की आवश्यकता है जो कि 0 के स्टार्ट इंडेक्स से पहले है -। तो सबस्ट्रिंग 223232, 443 और 34443553 हो जाएंगे

जवाबों:


144

। नेट फिडेल उदाहरण

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("223232-1.jpg".GetUntilOrEmpty());
        Console.WriteLine("443-2.jpg".GetUntilOrEmpty());
        Console.WriteLine("34443553-5.jpg".GetUntilOrEmpty());

        Console.ReadKey();
    }
}

static class Helper
{
    public static string GetUntilOrEmpty(this string text, string stopAt = "-")
    {
        if (!String.IsNullOrWhiteSpace(text))
        {
            int charLocation = text.IndexOf(stopAt, StringComparison.Ordinal);

            if (charLocation > 0)
            {
                return text.Substring(0, charLocation);
            }
        }

        return String.Empty;
    }
}

परिणाम:

223232
443
34443553
344

34

2
कृपया उन पर कृपा करें और त्रुटि की जाँच करने के साथ-साथ यह मानने की योजना बनाएं कि वह इस से बाहर कार्य करें :)
जोश

धन्यवाद मैं इसके करीब था, लेकिन उत्सुक था अगर किसी के पास इस कॉम्बो के अलावा इसे करने का एक अलग तरीका था। लेकिन हाँ यह बहुत अच्छा काम करता है और अभी भी बहुत छोटा है।
पॉजिटिव

14
यदि आप उचित "खोए हुए" चेकिंग के बिना एक-लाइनर चाहते थे तो आप कुछ ऐसा कर सकते हैं:string result = source.Substring(0, Math.Max(source.IndexOf('-'), 0))
ल्यूक

2
s.Substring(0, n)एक के बजाय इसका उपयोग s.Remove(n)तब किया जा सकता है जब यह ज्ञात हो (जैसे यहां) कि स्ट्रिंग की लंबाई sसख्ती से अधिक हो जाती है n
जेपी स्टिग नील्सन

@LukeH यदि IndexOf आपके उदाहरण में -1 लौटाता है, तो एक खाली स्ट्रिंग लौटा दी जाएगी, नहीं?
क्रश करें

124

विभाजन फ़ंक्शन का उपयोग करें ।

static void Main(string[] args)
{
    string s = "223232-1.jpg";
    Console.WriteLine(s.Split('-')[0]);
    s = "443-2.jpg";
    Console.WriteLine(s.Split('-')[0]);
    s = "34443553-5.jpg";
    Console.WriteLine(s.Split('-')[0]);

Console.ReadKey();
}

यदि आपके तार में एक नहीं है -तो आपको पूरी स्ट्रिंग मिल जाएगी।


4
और यदि आपके पास एक से अधिक हाइफ़न हैं, तो आपको अपने सरणी में कई तत्व मिलते हैं।
जेम्स डन

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

7
और कुछ वर्षों के बाद, मैंने महसूस किया है कि मैं जेम्स की बात को मानने के लिए बहुत जल्दी था। सवाल पूछता है कि एक निश्चित चरित्र से पहले स्ट्रिंग को कैसे खोजना है। उस चरित्र के आगे के उदाहरण इस प्रकार अप्रासंगिक हैं, और [0] लेना "बस काम" होगा। बेशक, यह अभी भी निर्भर करता है कि हम आने वाले डेटा पर कितना भरोसा करते हैं। क्या होगा अगर वहाँ कोई '-' है?
डोमिनिक क्रोनिन

1
मुझे लगता है कि @JamesDunne बिंदु यह था कि एक सरणी में विभाजित करके, आप अनावश्यक तारों का एक गुच्छा बना रहे हैं - अनावश्यक कचरा।
क्रश करें

1
मुझे "अनावश्यक कचरा" के बारे में चिंता नहीं होगी। इस तरह से बनाया गया कोई भी अतिरिक्त तार तुरंत पहुंच से बाहर हो जाएगा और इसलिए पीढ़ी 0 में एकत्र किया जाएगा, जो वास्तव में एक बहुत कम ओवरहेड है। कचरे के संग्रहकर्ता का डिज़ाइन स्पष्ट रूप से बड़ी संख्या में अल्पकालिक वस्तुओं के उपयोग की अनुमति देने के लिए है, जिनका उपयोग लगभग बिना किसी खर्च के किया जाता है।
डोमिनिक क्रोनिन

65
String str = "223232-1.jpg"
int index = str.IndexOf('-');
if(index > 0) {
    return str.Substring(0, index)
}

upvote क्योंकि मुझे विभाजक के सूचकांक को जानने की आवश्यकता है
पियरो अल्बर्टो

3
यह वास्तव में वैसा ही उत्तर है जैसा फ्रेडो ने दिया था (वर्तमान में शीर्ष उत्तर) सिवाय इसके कि यह उस मामले को संभालने में चूक जाता है जहां कोई मैच नहीं पाया जाता है।
डोमिनिक क्रोनिन

7

यह धागा शुरू होने के बाद से चीजें थोड़ी बढ़ गई हैं।

अब, आप उपयोग कर सकते हैं

string.Concat(s.TakeWhile((c) => c != '-'));

यह स्पष्ट IndexOf और सबस्ट्रिंग संयोजन के प्रदर्शन की तुलना कैसे करता है? मुझे लगता है कि यह एक StringBuilder के लिए प्रत्येक चरित्र जोड़ रहा है, और फिर अंत में एक स्ट्रिंग का उत्पादन। वहाँ भी फंक्शन कॉल की एक जोड़ी में मिलाया गया है। अच्छा होगा अगर सबस्ट्रिंग बस एक "लंबाई" तर्क अर्थ "स्ट्रिंग का अंत" के रूप में ले सकता है।
क्रश करें

1
यह दक्षता के लिए बदतर है। जैसा कि आप कहते हैं, यह एक स्ट्रिंग बिल्डर का उपयोग करता है, और निरीक्षण किया गया कोड प्रत्येक चरित्र पर ToString को कॉल करने के लिए प्रकट होता है। यदि आप एक से अधिक वर्णों की तलाश कर रहे हैं तो यह स्पष्ट है, क्योंकि आप लंबोदर को आसानी से लिख सकते हैं।
एंथनी वाइजर

4

एक तरह से यह करने के लिए उपयोग करने के लिए है String.Substringके साथ एक साथ String.IndexOf:

int index = str.IndexOf('-');
string sub;
if (index >= 0)
{
    sub = str.Substring(0, index);
}
else
{
    sub = ... // handle strings without the dash
}

स्थिति 0 पर शुरू होकर, सभी पाठों को वापस लौटाएँ, लेकिन शामिल नहीं, डैश।


यदि अनुक्रमणिका <= 0 आपको केवल string.empty को वापस करना चाहिए।
कोई रिफंड नहीं

5
@NRNR: अगर आप ऐसा कहते हैं। ओपी व्यापार आवश्यकताओं को जानता है, न कि आप या मैं
माइकल पेट्रोत्ता ने

0

ब्रेनकोर के जवाब पर बिल्डिंग:

    int index = 0;   
    str = "223232-1.jpg";

    //Assuming we trust str isn't null 
    if (str.Contains('-') == "true")
    {
      int index = str.IndexOf('-');
    }

    if(index > 0) {
        return str.Substring(0, index);
    }
    else {
       return str;
    }

0

आप इस उद्देश्य के लिए नियमित अभिव्यक्तियों का उपयोग कर सकते हैं, लेकिन अतिरिक्त अपवाद से बचने के लिए अच्छा है जब इनपुट स्ट्रिंग नियमित अभिव्यक्ति के खिलाफ बेमेल हो।

रेगेक्स पैटर्न से बचने के अतिरिक्त सिरदर्द से बचने के लिए सबसे पहले - हम उस उद्देश्य के लिए फ़ंक्शन का उपयोग कर सकते हैं:

String reStrEnding = Regex.Escape("-");

मुझे पता है कि यह कुछ भी नहीं करता है - जैसा कि "-" के रूप में ही है Regex.Escape("=") == "=", लेकिन यह उदाहरण के लिए फर्क पड़ेगा अगर चरित्र है @"\"

फिर हमें स्ट्रिंग के भीख मांगने से लेकर स्ट्रिंग समाप्त होने तक मेल खाना चाहिए, या वैकल्पिक रूप से यदि समाप्ति नहीं मिली है - तो कुछ भी मैच न करें। (खाली स्ट्रिंग)

Regex re = new Regex("^(.*?)" + reStrEnding);

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

और अंत में स्ट्रिंग और एक्स्ट्रेक्ट मैचेड पैटर्न के खिलाफ मैच करें:

String matched = re.Match(str).Groups[1].ToString();

और उसके बाद आप या तो अलग फ़ंक्शन लिख सकते हैं, जैसे कि यह एक अन्य उत्तर में किया गया था, या इनलाइन लैम्ब्डा फ़ंक्शन लिख सकता है। मैंने अब दोनों नोटेशन का उपयोग करते हुए लिखा है - इनलाइन लंबो फ़ंक्शन (डिफ़ॉल्ट पैरामीटर की अनुमति नहीं देता है) या अलग फ़ंक्शन कॉल।

using System;
using System.Text.RegularExpressions;

static class Helper
{
    public static string GetUntilOrEmpty(this string text, string stopAt = "-")
    {
        return new Regex("^(.*?)" + Regex.Escape(stopAt)).Match(text).Groups[1].Value;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Regex re = new Regex("^(.*?)-");
        Func<String, String> untilSlash = (s) => { return re.Match(s).Groups[1].ToString(); };

        Console.WriteLine(untilSlash("223232-1.jpg"));
        Console.WriteLine(untilSlash("443-2.jpg"));
        Console.WriteLine(untilSlash("34443553-5.jpg"));
        Console.WriteLine(untilSlash("noEnding(will result in empty string)"));
        Console.WriteLine(untilSlash(""));
        // Throws exception: Console.WriteLine(untilSlash(null));

        Console.WriteLine("443-2.jpg".GetUntilOrEmpty());
    }
}

Btw - रेगेक्स पैटर्न को बदलने के लिए या तो पैटर्न "^(.*?)(-|$)"तक लेने की अनुमति देगा "-"या यदि पैटर्न नहीं मिला - स्ट्रिंग के अंत तक सब कुछ उठाएं।


0

LINQY रास्ता

String.Concat ("223232-1.jpg" .TakeWhile (c => c! = '-'))

(लेकिन, आपको अशक्त करने के लिए परीक्षण करने की आवश्यकता है;)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.