C# 正则表达式筛选字符
本文关键字:字符 筛选 正则表达式 | 更新日期: 2023-09-27 18:31:48
我在 C# 中有一个字符串,我想过滤掉(扔掉)除数字以外的所有字符,即 0 到 9。例如,如果我有一个像"5435%$% r3443_+_+**╥╡←"这样的字符串,那么输出应该是54353443。如何使用正则表达式或 C# 中的其他内容来完成此操作?
谢谢
你不需要
正则表达式
var newstr = String.Join("", str.Where(c => Char.IsDigit(c)));
下面是
一些没有正则表达式的示例:
var str = "5435%$% r3443_+_+**╥╡←";
var result = new string(str.Where(o => char.IsDigit(o)).ToArray());
//Or you can make code above slightly more compact, using following syntax:
var result = new string(str.Where(char.IsDigit).ToArray());
从字符串中选择所有内容,即数字字符,并根据选择创建新字符串。
说到速度。
var sw = new Stopwatch();
var str = "5435%$% r3443_+_+**╥╡←";
sw.Start();
for (int i = 0; i < 100000; i++)
{
var result = new string(str.Where(o => char.IsDigit(o)).ToArray());
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); // Takes nearly 107 ms
sw.Reset();
sw.Start();
for (int i = 0; i < 100000; i++)
{
var s = Regex.Replace(str, @"'D", "");
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //Takes up to 600 ms
sw.Reset();
sw.Start();
for (int i = 0; i < 100000; i++)
{
var newstr = String.Join("", str.Where(c => Char.IsDigit(c)));
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //Takes up to 109 ms
因此,正则表达式实现可以预见地缓慢。连接和新字符串给出的结果非常相似,也可能取决于用例。没有使用手动字符串循环测试实现,我相信,它可能会给出最好的结果。
更新。还有正则表达式的RegexOptions.Compileed选项,用于示例。但是为了测试的清晰度,可以说,编译的正则表达式给出了近 150 毫秒以上的性能提升,这仍然相当慢(比其他慢 4 倍)。
代码:
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Diagnostics;
public class Foo
{
public static void Main()
{
string s = string.Empty;
TimeSpan e;
var sw = new Stopwatch();
//REGEX
sw.Start();
for(var i = 0; i < 10000; i++)
{
s = "123213!¤%//)54!!#¤!#%13425";
s = Regex.Replace(s, @"'D", "");
}
sw.Stop();
e = sw.Elapsed;
Console.WriteLine(s);
Console.WriteLine(e);
sw.Reset();
//NONE REGEX
sw.Start();
for(var i = 0; i < 10000; i++)
{
s = "123213!¤%//)54!!#¤!#%13425";
s = new string(s.Where(c => char.IsDigit(c)).ToArray());
}
sw.Stop();
e = sw.Elapsed;
Console.WriteLine(s);
Console.WriteLine(e);
}
}
输出:
1232135413425
00:00:00.0564964
1232135413425
00:00:00.0107598
结论:这显然有利于无正则表达式方法来解决此问题。
你试过什么?
static Regex rxNonDigits = new Regex( @"[^'d]+");
public static string StripNonDigits( string s )
{
return rxNonDigits.Replace(s,"") ;
}
或者可能更有效
public static string StripNonDigits( string s )
{
StringBuilder sb = new StrigBuilder(s.Length) ;
foreach ( char c in s )
{
if ( !char.IsDigit(c) ) continue ;
sb.Append(c) ;
}
return sb.ToString() ;
}
或等效的单行:
public static string StripNonDigits( string s )
{
return new StringBuilder(s.Length)
.Append( s.Where(char.IsDigit).ToArray() )
.ToString()
;
}
或者,如果您不关心其他区域性的数字,只关心 ASCII 十进制数字,您可以保存 [也许] 昂贵的查找并进行两次比较:
public static string StripNonDigits( string s )
{
return new StringBuilder(s.Length)
.Append( s.Where( c => c >= '0' && c <= '9' ).ToArray() )
.ToString()
;
}
应该注意的是,LINQ 解决方案几乎肯定需要构造一个中间数组(使用 StringBuilder
不需要构造。您还可以使用 LINQ 聚合:
s.Where( char.IsDigit ).Aggregate(new StringBuilder(s.Length), (sb,c) => sb.Append(c) ).ToString()
方法不止一种!
^
从匹配项中排除表达式。 将其与 'd
一起使用,它匹配数字 0-9,并将其替换为任何内容。
var cleanString = Regex.Replace("123abc,.é", "^'d", "");
您可以简单地执行以下操作,字符类[ ]
内部的插入符号(^
)是否定运算符。
var pattern = @"[^0-9]+";
var replaced = Regex.Replace("5435%$% r3443_+_+**╥╡←", pattern, "");
输出:
54353443