2

C# に文字列があり、0 から 9 までの数字以外のすべての文字を除外 (破棄) したいと考えています。たとえば、"5435%$% r3443_+_+**╥╡← "、出力は 54353443 になるはずです。C# で正規表現などを使用してこれを行うにはどうすればよいでしょうか?

ありがとう

4

6 に答える 6

6

正規表現を使用しない例を次に示します。

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.Compiled オプションがあり、例からの使用が意図されていました。しかし、テストを明確にするために、コンパイルされた正規表現は、例で 150 ミリ秒近くパフォーマンスを向上させますが、それでもかなり遅いです (他のものより 4 倍遅い)。

于 2013-09-18T23:18:36.503 に答える
6

これには正規表現は必要ありません

 var newstr = String.Join("", str.Where(c => Char.IsDigit(c)));
于 2013-09-18T23:18:50.383 に答える
2

何を試しましたか?

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 10 進数のみを気にする場合は、[おそらく] コストのかかるルックアップを節約して、2 つの比較を行うことができます。

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()

それを行う方法は複数あります。

于 2013-09-18T23:20:39.543 に答える
1

次のように簡単に実行できます。^文字クラス内のキャレット ( )[ ]は否定演算子です。

var pattern = @"[^0-9]+";
var replaced = Regex.Replace("5435%$% r3443_+_+**╥╡←", pattern, "");

出力:

54353443
于 2013-09-18T23:23:20.363 に答える
1

^、一致から式を除外します。0 ~ 9 の数字に一致する とともに使用し\d、これを何も置き換えません。

var cleanString = Regex.Replace("123abc,.é", "^\d", "");
于 2013-09-18T23:23:42.817 に答える