गैर-संख्यात्मक को खाली स्ट्रिंग से बदलें


125

हमारी परियोजना में आवश्यकता पर त्वरित जोड़ें फ़ोन नंबर रखने के लिए हमारे DB में एक फ़ील्ड केवल 10 वर्णों को अनुमति देने के लिए सेट है। तो, अगर मैं पास हो गया "(913) -444-5555" या कुछ और, क्या किसी तरह के विशेष प्रतिस्थापन फ़ंक्शन के माध्यम से एक स्ट्रिंग चलाने का एक त्वरित तरीका है कि मैं इसे अनुमति देने के लिए वर्णों का एक सेट पारित कर सकता हूं?

Regex?

जवाबों:


251

निश्चित रूप से regex:

string CleanPhone(string phone)
{
    Regex digitsOnly = new Regex(@"[^\d]");   
    return digitsOnly.Replace(phone, "");
}

या एक वर्ग के भीतर हर समय regex बनाने से बचने के लिए:

private static Regex digitsOnly = new Regex(@"[^\d]");   

public static string CleanPhone(string phone)
{
    return digitsOnly.Replace(phone, "");
}

आपके वास्तविक दुनिया के इनपुट के आधार पर, आप चाहते हैं कि वहाँ कुछ अतिरिक्त तर्क दिया जाए जैसे कि स्ट्रिप आउट 1 (लंबी दूरी के लिए) या एक्स या एक्स (एक्सटेंशन के लिए) के लिए कुछ भी।


यह बिल्कुल सही है। यह केवल कुछ समय के लिए उपयोग किया जाता है, इसलिए हमें एक वर्ग बनाने की आवश्यकता नहीं है, और जहाँ तक अग्रणी 1 है, बुरा विचार नहीं है। लेकिन मुझे लगता है कि मैं कम से कम इस परियोजना में केस के आधार पर मामला संभालूंगा। धन्यवाद फिर से - अगर मैं फिर से बढ़ा सकता हूं, तो मैं करूंगा।
मैट डावी

1
मैं किसी के लिए स्ट्रिंग क्लास के लिए एक एक्सटेंशन विधि संस्करण पोस्ट करने की प्रतीक्षा कर रहा हूं :)
जोएल कोएहॉर्न

@ जोल I ने नीचे विस्तार विधि संस्करण जोड़ा। लगता है कि टिप्पणियाँ मार्कडाउन का समर्थन नहीं करती हैं।
एरॉन

13
नोट [^\d]को सरल किया जा सकता है\D
pswg

इस उत्तर को संयुक्त करें (वर्ग में रेगेक्स को कैशिंग) विस्तार विधि के साथ एक नीचे :)
विन्सेन्ट वैंकलबर्ग

73

आप इसे आसानी से regex के साथ कर सकते हैं:

string subject = "(913)-444-5555";
string result = Regex.Replace(subject, "[^0-9]", ""); // result = "9134445555"

2
एक महान जवाब होने के लिए अपवित्र, लेकिन जोएल ने आपको हरा दिया। हालांकि उत्तर के लिए धन्यवाद - मैं वास्तव में कई स्रोतों से पुष्टि देखना पसंद करता हूं।
मैट दाऊद

@JoSmo निष्पक्ष होने के लिए, योएल को एक-लाइनर के रूप में सुंदर रूप से परिवर्तित किया जा सकता है। (लेकिन मैंने यह भी उतारा: D)
मेजी Xy

40

आपको Regex का उपयोग करने की आवश्यकता नहीं है।

phone = new String(phone.Where(c => char.IsDigit(c)).ToArray())

3
अच्छा उत्तर, रेग्युलर एक्सप्रेशंस नामस्थान के लिए अधिक संदर्भ क्यों जोड़ें
BTE

1
@BTE क्योंकि यह एक छोटा-सा हाथ है जो बस उपयोग कर रहा हैsystem.linq;
एरिक मिलियट-मार्टिनेज

1
रेगेक्स समाधान की तुलना में यह कितना अच्छा प्रदर्शन करता है?
शाविस

2
LINQ solution results के लिए @ Max-PC के बेंचमार्क कोड में एक टेस्ट जोड़ना - StringBuilder: 273ms, Regex: 2096ms, LINQ: 658ms। StringBuilder की तुलना में धीमी लेकिन अभी भी रेगेक्स की तुलना में काफी तेज है। यह देखते हुए कि 1,000,000 प्रतिस्थापनों को बेंचमार्क कर रहा है, ज्यादातर परिदृश्यों के लिए स्ट्रिंगब्यूलर और लिनक्यू समाधानों के बीच प्रभावी अंतर शायद नकारात्मक है।
क्रिस प्रैट

Regex के लिए @ChrisPratt, क्या आपने प्रत्येक बार एक नया regex बनाया है, या किसी मौजूदा का उपयोग करें? इससे प्रदर्शन पर बड़ा असर पड़ सकता है।
carlin.scott

23

यहाँ यह करने का विस्तार विधि तरीका है।

public static class Extensions
{
    public static string ToDigitsOnly(this string input)
    {
        Regex digitsOnly = new Regex(@"[^\d]");
        return digitsOnly.Replace(input, "");
    }
}

8

.NET में रेगेक्स विधियों का उपयोग करके आप \ D का उपयोग करके किसी भी गैर-संख्यात्मक अंक का मिलान करने में सक्षम होना चाहिए, जैसे:

phoneNumber  = Regex.Replace(phoneNumber, "\\D", String.Empty);

5
यह काफी सही नहीं है। Regex में बचने के लिए आपको एक @ या "\\ D" की आवश्यकता है। इसके अलावा, आपको ""
ब्रायन

5

कैसे एक विस्तार विधि के बारे में जो रेगेक्स का उपयोग नहीं करता है।

यदि आप रेगेक्स विकल्पों में से एक से चिपकते हैं तो कम से कम RegexOptions.Compiledस्टैटिक वेरिएबल में उपयोग करें ।

public static string ToDigitsOnly(this string input)
{
    return new String(input.Where(char.IsDigit).ToArray());
}

यह उस्मान जफर के जवाब को एक विधि समूह में परिवर्तित कर देता है।


4

सर्वोत्तम प्रदर्शन और कम मेमोरी खपत के लिए, यह कोशिश करें:

using System;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;

public class Program
{
    private static Regex digitsOnly = new Regex(@"[^\d]");

    public static void Main()
    {
        Console.WriteLine("Init...");

        string phone = "001-12-34-56-78-90";

        var sw = new Stopwatch();
        sw.Start();
        for (int i = 0; i < 1000000; i++)
        {
            DigitsOnly(phone);
        }
        sw.Stop();
        Console.WriteLine("Time: " + sw.ElapsedMilliseconds);

        var sw2 = new Stopwatch();
        sw2.Start();
        for (int i = 0; i < 1000000; i++)
        {
            DigitsOnlyRegex(phone);
        }
        sw2.Stop();
        Console.WriteLine("Time: " + sw2.ElapsedMilliseconds);

        Console.ReadLine();
    }

    public static string DigitsOnly(string phone, string replace = null)
    {
        if (replace == null) replace = "";
        if (phone == null) return null;
        var result = new StringBuilder(phone.Length);
        foreach (char c in phone)
            if (c >= '0' && c <= '9')
                result.Append(c);
            else
            {
                result.Append(replace);
            }
        return result.ToString();
    }

    public static string DigitsOnlyRegex(string phone)
    {
        return digitsOnly.Replace(phone, "");
    }
}

मेरे कंप्यूटर में परिणाम है:
Init ...
समय: 307
समय: 2178


बेंचमार्क दिखाने के लिए +1। दिलचस्प है कि स्ट्रिंग StringBuilder के साथ RegExforms RegEx, हालांकि मुझे लगता है कि यह समझ में आता है जब RegEx को शायद बहुत सारे नियमों के माध्यम से यह तय करना है कि क्या करना है।
स्टीव

3

मुझे यकीन है कि इसे करने के लिए एक अधिक कुशल तरीका है, लेकिन मैं शायद ऐसा करूंगा:

string getTenDigitNumber(string input)
{    
    StringBuilder sb = new StringBuilder();
    for(int i - 0; i < input.Length; i++)
    {
        int junk;
        if(int.TryParse(input[i], ref junk))
            sb.Append(input[i]);
    }
    return sb.ToString();
}

यह मेरी पहली वृत्ति थी, और यह भी कि मैंने यहाँ क्यों पूछा। RegEx मुझे एक बेहतर समाधान की तरह लगता है। लेकिन उत्तर के लिए धन्यवाद!
मैट डावी

-1

इसे इस्तेमाल करे

public static string cleanPhone(string inVal)
        {
            char[] newPhon = new char[inVal.Length];
            int i = 0;
            foreach (char c in inVal)
                if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0)
                    newPhon[i++] = c;
            return newPhon.ToString();
        }

return newPhone.ToString();"System.Char []" लौटाएगा। मैं तुम्हें मतलब लगता है return new string(newPhone);, लेकिन यह भी बाहर संख्या 0 और की वजह से 9 फ़िल्टर कर रही है >और <बजाय >=और <=। लेकिन तब भी स्ट्रिंग में अनुगामी रिक्त स्थान होंगे क्योंकि newPhonसरणी को उसके होने की आवश्यकता से अधिक लंबा है।
जुहार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.