简体   繁体   中英

how to write regex for “123456#” to print 123456?

Hi I need a regex to replace # or * with ""(emptyString) I have tried with /[\\\\*\\\\#]/g but does not seem to be working.

http://ideone.com/MtjsX5

please need your help in this.

I am actually using this a Grxml grammar as below

SWI_meaning          = DIGITS.SWI_literal.replace( /[ ]+/g, '' );
 SWI_meaning          = SWI_meaning.replace( /[\*\#]/g, '' );

Thanks

Rather than regex, you can use char.IsDigit to filter out only digits from the string. Try the following.

string str = "123456#";
string newString = string.Join("",
                         str.Select(r=> char.IsDigit(r) ? r.ToString():""));

EDIT: courtesy @ LB

string newString = String.Join("",str.Where(char.IsDigit));
string str = "123456#";
string clean = Regex.Replace(str, @"[#*]", string.Empty);

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

And to follow Jamie Zawinski's advice you could simply call replace twice.

String str = "123456#*42#";
var result = str.Replace("*", "").Replace("#", "");

PS. Not that it really matters but Replace Replace seems to be the fastest. https://gist.github.com/4109899 DS.

One option that seems to be missing, and then you're almost completely covered. For removal of just two chars, the usage of Replace.Replace is the fastest, closely followed by array operations and stringbuilders.

Linq Where and the usage of string.Join make everything a tad bit slower, though it doesn't really matter much.

You'll be surprised to see that Regex (at least under .NET 4.5) isn't as slow as you might expect. It's even faster than using Linq. Maybe if you use compiled expressions or delegates, you might be able to speed up the Linq expressions a little more.

When you need to replace larger parts from the string or more characters than just two chars the statistics might change.

    static void Main(string[] args)
    {
        string str = "123456#23876587234687237*723547623547523745273#";

        Console.WriteLine("Join+Where");
        Test(s => String.Join("",s.Where(char.IsDigit)), str);

        Console.WriteLine("ArrayOperation");
        Test(s => new string(Array.FindAll(s.ToCharArray(), char.IsDigit)), str);

        Console.WriteLine("Join+Select");
        Test(s => string.Join("", s.Select(r=> char.IsDigit(r) ? r.ToString():"")), str);

        Console.WriteLine("ReplaceReplace");
        Test(s => s.Replace("*", "").Replace("#", ""), str);

        Console.WriteLine("Regex");
        Test(s => Regex.Replace(s, "[#*]", ""), str);

        Console.WriteLine("Regex");
        Regex rx = new Regex("[#*]", RegexOptions.Compiled);
        rx.Match(""); // Precompile for better results
        Test(s => rx.Replace(s, ""), str);

        Console.WriteLine("StringBuilder");
        Test(s => new StringBuilder(s).Replace("*", "").Replace("#", "").ToString(), str);
        Console.ReadLine();

    }

    public static void Test(Func<string,string> proposedSolution, string input)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Thread.Sleep(5000);

        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i = 0; i < 1000; i++)
        {
            string val = proposedSolution(input);
            Debug.Write(val);
        }

        sw.Stop();

        Console.WriteLine(sw.ElapsedMilliseconds);
    }

Output for "123456#23876587234687237*723547623547523745273#" is as follows (you'll notice that if regex is used properly it isn't as slow as people would let you believe:

Join+Where
88
ArrayOperation
25
Join+Select
45
ReplaceReplace
18
Regex
39
Regex+Compiled
41
StringBuilder
19

This might become more interesting when you need to replace more than just everything but digits. Or more specifically "#" and "*". But in the end, creating a simple test and then choosing the method that is easiest to understand and performing is probably the best solution.

One thing to point out : Not all solutions provided do exactly the same thing. While some only keep numbers, other specifically remove two characters from the given input. For you sample, both options seem to be valid, but it's important to understand the differences.

The same options that remove just # and * using LINQ:

        char[] Removechars = new[] { '#', '*' };

        Console.WriteLine("Join+Where");
        Test(s => String.Join("", s.Where(c => !Removechars.Contains(c))), str);

        Console.WriteLine("ArrayOperation");
        Test(s => new string(Array.FindAll(s.ToCharArray(), c => !Removechars.Contains(c))), str);

        Console.WriteLine("Except");
        Test(s => new string(s.ToCharArray().Except(Removechars).ToArray()), str);

        Console.WriteLine("Join+Select");
        Test(s => string.Join("", s.Select(c => !Removechars.Contains(c) ? c.ToString():"")), str);

These options are all slower than using IsDigit or !IsDigit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM