C# 将非数字替换为空字符串

C# 将非数字替换为空字符串,c#,regex,string,phone-number,C#,Regex,String,Phone Number,我们项目中的快速附加需求。数据库中用于保存电话号码的字段设置为仅允许10个字符。那么,如果我通过了“(913)-444-5555”或其他任何程序,是否有一种快速的方法可以通过某种特殊的替换函数运行字符串,我可以向它传递一组允许的字符 正则表达式?绝对正则表达式: string CleanPhone(string phone) { Regex digitsOnly = new Regex(@"[^\d]"); return digitsOnly.Replace(phone,

我们项目中的快速附加需求。数据库中用于保存电话号码的字段设置为仅允许10个字符。那么,如果我通过了“(913)-444-5555”或其他任何程序,是否有一种快速的方法可以通过某种特殊的替换函数运行字符串,我可以向它传递一组允许的字符

正则表达式?

绝对正则表达式:

string CleanPhone(string phone)
{
    Regex digitsOnly = new Regex(@"[^\d]");   
    return digitsOnly.Replace(phone, "");
}
或在类内,以避免始终重新创建正则表达式:

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

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

根据您在现实世界中的输入,您可能需要一些额外的逻辑来执行某些操作,例如去掉前导1(用于长途)或任何尾随x或x的操作(用于扩展)。

我相信有一种更有效的方法来执行此操作,但我可能会这样做:

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();
}
string getTenDigitNumber(字符串输入)
{    
StringBuilder sb=新的StringBuilder();
for(inti-0;i
使用正则表达式,您可以轻松完成:

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

使用.NET中的正则表达式方法,您应该能够使用\D匹配任何非数字数字,如下所示:

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

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();
        }
publicstaticstringcleanphone(字符串无效)
{
char[]newPhon=新字符[无效长度];
int i=0;
foreach(无效字符c)
如果(c.CompareTo('0')>0和&c.CompareTo('9')<0)
newPhon[i++]=c;
返回newPhon.ToString();
}

以下是扩展方法

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

你不需要使用正则表达式

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

一个不使用正则表达式的扩展方法怎么样

如果您坚持使用其中一个正则表达式选项,至少在静态变量中使用
RegexOptions.Compiled

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

这建立在Usman Zafar的答案转换为方法组的基础上。

要获得最佳性能和更低的内存消耗,请尝试以下方法:

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, "");
    }
}
使用系统;
使用系统诊断;
使用系统文本;
使用System.Text.RegularExpressions;
公共课程
{
私有静态正则表达式digitsOnly=新正则表达式(@“[^\d]”);
公共静态void Main()
{
Console.WriteLine(“Init…”);
string phone=“001-12-34-56-78-90”;
var sw=新秒表();
sw.Start();
对于(int i=0;i<1000000;i++)
{
仅数字(电话);
}
sw.Stop();
Console.WriteLine(“时间:+sw.ElapsedMilliseconds”);
var sw2=新秒表();
sw2.Start();
对于(int i=0;i<1000000;i++)
{
DigitOnlyRegex(电话);
}
sw2.Stop();
Console.WriteLine(“时间:+sw2.ElapsedMilliseconds”);
Console.ReadLine();
}
公共静态字符串DigitsOnly(字符串电话,字符串替换=null)
{
如果(replace==null)replace=“”;
如果(phone==null)返回null;
var结果=新的StringBuilder(phone.Length);
foreach(电话中的字符c)

如果(c>='0'&&c这很好。这只使用了几次,所以我们不需要创建类,对于最前面的1,这是一个不错的主意。但我认为我更愿意逐个处理,至少在这个项目中是这样。再次感谢——如果我能再次投票,我会的。我正在等待有人发布的扩展方法版本对于字符串类:)@Joel I添加了下面的扩展方法版本。猜测注释不支持标记。注意
[^\d]
可以简化为
\d
将此答案(在类中缓存正则表达式)与下面的扩展方法一结合起来:)这是我的第一反应,也是我为什么在这里提问的原因。RegEx对我来说似乎是一个更好的解决方案。但是谢谢你的回答!投票结果是一个很好的答案,但是Joel击败了你。谢谢你的回答——我真的很喜欢看到来自多个来源的确认。@JoSmo公平地说,Joel的可以转换成一行漂亮的triv(但我也向上投票:D)这不太正确。您需要@或“\\D”来转义正则表达式中的\。此外,您应该使用String.Empty而不是“”回答得好,为什么要增加对正则表达式的引用namespace@BTE因为这是一个简单的使用
system.linq;
与Regex解决方案相比,它的性能如何?在@Max PC的linq解决方案基准代码中添加一个测试会导致--StringBuilder:273ms,Regex:2096ms,linq:658ms。比St慢ringBuilder,但仍然比Regex快得多。鉴于这是对1000000次替换的基准测试,大多数情况下StringBuilder和LINQ解决方案之间的有效差异可能是可以忽略的。@ChrisPratt对于Regex,您是每次创建一个新的Regex,还是重复使用一个现有的Regex?这可能会对性能产生很大影响异常。
return newPhone.ToString();
将返回“System.Char[]”。我想你的意思是
返回新字符串(newPhone);
,但这也过滤掉了数字0和9,因为
=/code>和
+1。有趣的是,使用StringBuilder的循环优于正则表达式,尽管我想当正则表达式可能必须通过大量规则来决定要做什么时,这是有意义的。