文字列配列に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)
例外がスローされます:
ソースアレイ内の少なくとも一つの要素は、先の配列型にダウンキャストすることができませんでした。
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();
夜03時02分で、7月10日'12に答え
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
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
午後01時55時5月14日'14答え
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;
}
}
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答え
2,1631421
-
1
うわ...その正規表現を見て恐ろしいです。ところで、MailAddressオブジェクトを使用し、電子メールを検証するための絶対確実な正規表現が存在しないとして。 stackoverflow.com/a/201378/2437521 - C. Tewalt 午前18時19分で、8月5日'14