文字列配列にMatchCollectionの変換

文字列配列にMatchCollectionの変換

質問をします

 

 

65

 

9

文字列配列にMatchCollectionを変換するには、このより良い方法はありますか?

MatchCollection mc = Regex.Matches(strText, @"\b[A-Za-z-']+\b");
string[] strArray = new string[mc.Count];
for (int i = 0; i < mc.Count;i++ )
{
    strArray[i] = mc[i].Groups[0].Value;
}

PS:  mc.CopyTo(strArray,0) 例外がスローされます:

ソースアレイ内の少なくとも一つの要素は、先の配列型にダウンキャストすることができませんでした。

C#の 配列の 正規表現

シェアはこの質問を改善します

午前17時40分に8月20日'18で編集

ggorlen

10k41229

15:00 7月10日'12を尋ねました

意志

1,02111114

コメントを追加

5件の回答

アクティブ最古

138

 

試してみてください。

var arr = Regex.Matches(strText, @"\b[A-Za-z-']+\b")
    .Cast<Match>()
    .Select(m => m.Value)
    .ToArray();

シェアは、この答えを改善します

午前16時49分で、3月6日'14で編集

夜03時02分で、7月10日'12に答え

デイブBISH

15k63757

  • 1

    私が使用しているだろう  OfType<Match>() 。このために代わりの  Cast<Match>() その後、再び、結果は同じだろう...。アレックス  夜03時05分で、7月10日'12 

  • 3

    @Alexあなたはすべてが返されたことを知っていることになります  Matchので、実行時にそれを再度チェックする必要はありません。Cast より多くの意味があります。Servy  15時08分で、7月10日'12

  • 2

    @DaveBish私は以下のいくつかのベンチマークソートのコードを掲載、  OfType<> わずかに速いことが判明しました。アレックス 15時29分で、7月10日'12

  • 1

    @Frontenderman -いや、私はちょうどaskersの質問でそれを合わせた-  デイブBISH  3月6日'14を夜4時48分で

  • 1

    あなたはそれを有効にする簡単なコマンドと思うだろう  MatchCollection に  string[]、それがためであるとして、  Match.ToString()これは、多くの中で必要な最後のタイプは明らかだ  Regex 用途は文字列になりますので、変換するのは簡単されている必要があります。n00dles  16時19分で、6月10日'17

表示さ  6件の  以上のコメントを

 

26

 

デイブBISHの答えは良好であり、正常に動作します。

交換することが、それは注目に値します  Cast<Match>() とすると、  OfType<Match>() 物事をスピードアップします。

コードウォールドは次のようになります。

var arr = Regex.Matches(strText, @"\b[A-Za-z-']+\b")
    .OfType<Match>()
    .Select(m => m.Groups[0].Value)
    .ToArray();

結果はまったく同じです(とOPの問題とまったく同じ方法で対処)が、巨大な文字列のためにそれが高速です。

テストコード:

// put it in a console application
static void Test()
{
    Stopwatch sw = new Stopwatch();
    StringBuilder sb = new StringBuilder();
    string strText = "this will become a very long string after my code has done appending it to the stringbuilder ";

    Enumerable.Range(1, 100000).ToList().ForEach(i => sb.Append(strText));
    strText = sb.ToString();

    sw.Start();
    var arr = Regex.Matches(strText, @"\b[A-Za-z-']+\b")
              .OfType<Match>()
              .Select(m => m.Groups[0].Value)
              .ToArray();
    sw.Stop();

    Console.WriteLine("OfType: " + sw.ElapsedMilliseconds.ToString());
    sw.Reset();

    sw.Start();
    var arr2 = Regex.Matches(strText, @"\b[A-Za-z-']+\b")
              .Cast<Match>()
              .Select(m => m.Groups[0].Value)
              .ToArray();
    sw.Stop();
    Console.WriteLine("Cast: " + sw.ElapsedMilliseconds.ToString());
}

出力は次のとおりです。

OfType: 6540
Cast: 8743

以下のために  非常に長い  キャストの文字列()ので遅いです。

シェアは、この答えを改善します

午前15時28時7月10日'12に答え

アレックス

20.4k33065

  • 1

    非常に驚くべき!OfTypeがしなければならないことを考えると(私は考えているだろう?)出演理由上の任意のアイデアは、<>が遅くなり、どこかの内部比較キャスト「ですか」?私は何も得ませんでした!デイブBISH  8時51分で、7月11日'12

  • 私は正直に手掛かりを持っていないが、それは右の私に「感じ」(> <キャストフィルタは、よく、キャストは...ちょうどOfType <>されている) -  アレックス・  9時55分で、7月11日'12

  • 2

    stackoverflow.com/questions/11430570/...  -  デイブBISH  10時27分で、7月11日'12

  • より多くのベンチマークは、この特定の結果が使用される特定のLINQの拡張よりはRegexすることになっている示しているように見える-  アレックス  13:14で、7月11日'12

コメントを追加

5

 

私はアレックスが掲載していることをまったく同じベンチマークを実行し、時にはことがわかっ  Cast 速かったし、時には  OfType 速かったが、両者の差はごくわずかでした。醜いながらしかし、ループの他の二つの両方よりも一貫して高速です。

Stopwatch sw = new Stopwatch();
StringBuilder sb = new StringBuilder();
string strText = "this will become a very long string after my code has done appending it to the stringbuilder ";
Enumerable.Range(1, 100000).ToList().ForEach(i => sb.Append(strText));
strText = sb.ToString();

//First two benchmarks

sw.Start();
MatchCollection mc = Regex.Matches(strText, @"\b[A-Za-z-']+\b");
var matches = new string[mc.Count];
for (int i = 0; i < matches.Length; i++)
{
    matches[i] = mc[i].ToString();
}
sw.Stop();

結果:

OfType: 3462
Cast: 3499
For: 2650

シェアは、この答えを改善します

午前20時58分で、8月5日'14で編集

午後01時55時5月14日'14答え

デビッドDeMar

1,00011534

  • 何の驚きは、LINQというforループよりも遅くはありません。LINQのは一部の人のために書くと費用の実行時に彼らの生産性を「増やす」しやすいかもしれません。それは時々良いことができます-  gg89  9月23日'15 6時01分で 

  • だから、オリジナルのポストは実際に最も効率的な方法です。n00dles  午後04時21時6月10日'17 

コメントを追加

1

 

一つは、また、この拡張メソッドの使用はの迷惑に対処するために作ることができる  MatchCollection 汎用的なものではありません。ではない、それは大したことだが、これはほぼ確実に、よりパフォーマンスよりである  OfType か、  Castそれだけで、それらの両方が、またしなければならないこれは、列挙しているため、。

(サイドノート:私は.NETチームが作るすることが可能であるかどうか疑問  MatchCollection のジェネリック継承  ICollection と  IEnumerable ?将来的にはその後、我々はすぐにLINQが使用可能に変換するには、この余分なステップを必要としません)。

public static IEnumerable<Match> ToEnumerable(this MatchCollection mc)
{
    if (mc != null) {
        foreach (Match m in mc)
            yield return m;
    }
}

シェアは、この答えを改善します

午後12時01分で、1月9日に編集

ローレン・ヴァンSloun

1,03531219

午後06時23分で2月14日'18答え

ニコラス・ピーターセン

4,66963660

コメントを追加

0

 

次のコードを考えてみましょう...

var emailAddress = "[email protected]; [email protected]; [email protected]";
List<string> emails = new List<string>();
emails = Regex.Matches(emailAddress, @"([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})")
                .Cast<Match>()
                .Select(m => m.Groups[0].Value)
                .ToList();

がんばろう!

シェアは、この答えを改善します

2時01分で、11月22日'13答え

gpmurthy

2,1631421

  • 1

    うわ...その正規表現を見て恐ろしいです。ところで、MailAddressオブジェクトを使用し、電子メールを検証するための絶対確実な正規表現が存在しないとして。 stackoverflow.com/a/201378/2437521  -  C. Tewalt  午前18時19分で、8月5日'14

コメントを追加

おすすめ

転載: blog.csdn.net/cxu123321/article/details/92067172