トップ回答者
正規表現マッチングで処理が帰ってこない

質問
-
いつもお世話になっております。下記のコードを実行すると、Match()から処理が帰ってきません。数分すると帰ってきますが、もっと長い文字列になると数時間帰ってきません。これはどうしようもないでしょうか。宜しくお願い致します。
環境:WinXP VS2005 C#
string sz1, sz2;
Match match;
Regex regex;sz1 = "(.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*) (.*-?[0-9]+.?[0-9]*)";
sz2 = "55.55 55.55 55.55 55.55 55.55 55.55 55.55 55.55 55.55 55.55";
regex = new Regex( sz1 );
match = regex.Match( sz2 );
回答
-
取り敢えずなのですが、この "(.*-?[0-9]+.?[0-9]*)" の1つ1つは "55.55" に対応することを意図しているのでしょうか?
試しに、sz1 = "(.*-?[0-9]+.?[0-9]*)" と sz2 に対して regex.Match(sz2); をかけてみると、結果の match は sz2 全体になってしまいます。
".*" の記述が最大限に働いて、".*" が最後の1つ前の 55.55 まで全部一致してしまった結果だと思います。ですので「ありそうなパターンが多すぎる」ことで Regex に時間がかかり過ぎているのではないかと推測されます。
区切り記号としてスペースを仮定されているのでしたら、次のように sz1 を書き換えられるのは如何でしょうか?
sz1 ="\\s*(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)";
あと、sz1 には "\\s*(-?[0-9]+\\.?[0-9]*)" を記述して、
regex = new Regex(sz1);
match = regex.Match(sz2);
while (match.Success)
{
Group g = match.Groups[0];
CaptureCollection cc = g.Captures;
for (int j = 0; j < cc.Count; j++)
{
Capture c = cc[j];
System.Console.WriteLine("Capture" + j + "='" + c + "', Position=" + c.Index);
}
System.Console.WriteLine(match.Index);
match = match.NextMatch();
}のように NextMatch をとっていく方法もあると思います。
すべての返信
-
取り敢えずなのですが、この "(.*-?[0-9]+.?[0-9]*)" の1つ1つは "55.55" に対応することを意図しているのでしょうか?
試しに、sz1 = "(.*-?[0-9]+.?[0-9]*)" と sz2 に対して regex.Match(sz2); をかけてみると、結果の match は sz2 全体になってしまいます。
".*" の記述が最大限に働いて、".*" が最後の1つ前の 55.55 まで全部一致してしまった結果だと思います。ですので「ありそうなパターンが多すぎる」ことで Regex に時間がかかり過ぎているのではないかと推測されます。
区切り記号としてスペースを仮定されているのでしたら、次のように sz1 を書き換えられるのは如何でしょうか?
sz1 ="\\s*(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)\\s+(-?[0-9]+\\.?[0-9]*)";
あと、sz1 には "\\s*(-?[0-9]+\\.?[0-9]*)" を記述して、
regex = new Regex(sz1);
match = regex.Match(sz2);
while (match.Success)
{
Group g = match.Groups[0];
CaptureCollection cc = g.Captures;
for (int j = 0; j < cc.Count; j++)
{
Capture c = cc[j];
System.Console.WriteLine("Capture" + j + "='" + c + "', Position=" + c.Index);
}
System.Console.WriteLine(match.Index);
match = match.NextMatch();
}のように NextMatch をとっていく方法もあると思います。