-1

私は次の形式でたくさんの文字列を与えられます:

ASDF [         6]

ZXC[1]

OtPasd[ 4 ]

asdffa[   7]

有効な文字列の角かっこの間の整数を取得する必要があります。文字列は次の場合にのみ有効です。

  1. 角かっこの間には空白のみがあります。IE:「ZXCV[a2]」は無効です
  2. すべてのブラケットが適切に閉じられています。IE:「qwr[2」は無効です
  3. すべてのストリングには、1つの開閉ブラケットのみがあります。IE:"zxcf[4]]]"は無効です

大量の文字列を取得しているので、正規表現を避けたいので、計算量の少ないものが望ましいでしょう。

整数を検証および取得するための最もクリーンで最速の方法は何ですか?

編集:正規表現を使用することにしました。

4

5 に答える 5

1

私の個人的な意見では、最もクリーンな解決策は正規表現を使用することです。しかし、それが計算集約的であるかどうかを推測する代わりに、私はむしろそれをベンチマークしたいと思います。これがコードです。

const int Count = 10000000;
const string testString = "<whatever>";

// Solution No. 1: use Regex.Match()    
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < Count; i++)
{
    var match = Regex.Match(@"\[\s*(\d+)\s*\]$", testString);
    if (!match.Success)
        continue;
    var number = int.Parse(match.Groups[1].Value);
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

// Solution No. 2: use IndexOf() and Substring() shenanigans
sw.Start();
for (int i = 0; i < Count; i++)
{
    var lb = testString.IndexOf('[');
    var rb = testString.LastIndexOf(']');
    if (lb < 0 || rb != testString.Length - 1)
        continue;
    var str = testString.Substring(lb + 1, rb - lb - 1);
    int number;
    if (!int.TryParse(str, out number))
        continue;
    // use the number
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);

そしてここに結果があります:

Solution  |  testString  |   Time (ms)  | Comment
----------|--------------|--------------|-----------------------
     1    | abc [      ] |    4476      | Invalid input string
     2    | abc [      ] |    6594      | Invalid input string
     1    | abc[1234]    |    4446      | Valid input string
     2    | abc[1234]    |    6290      | Valid input string

ご覧のとおり、正規表現ソリューションは短くてクリーンであるだけでなく、実際には高速です。また、さまざまな入力文字列で遊んでいる場合、入力文字列が長いほど、最初のソリューションと2番目のソリューションの間のギャップが大きくなることに気付くでしょう。

于 2012-09-11T14:14:41.740 に答える
0

この正規表現を試してください:

\[\s*(\d+)\s*\]$
于 2012-09-11T13:29:44.020 に答える
0

この正規表現(?m)(?!<=\[)(\[\s*)(\d+)(\s*\])(?!\]) をマッチグループで整数に使用します

于 2012-09-11T13:29:58.710 に答える
0

正規表現の使用を避けたい場合...IndexOf/ LastIndexOfを使用してから、残りの文字列を解析することは、必要なものに適していますか?

于 2012-09-11T13:32:58.640 に答える
0

角かっこの間にintを入れるには、次の方法を試すこともできます。

string tmpString = "ASDF [         6]";
int start = tmpString.IndexOf('[') + 1;
int length = tmpString.IndexOf(']') - start;
string subString = tmpString.Substring(start, length);
int tempInt;
if(Int.TryParse(subString, out tempInt))
return tempInt;
于 2012-09-11T13:36:32.667 に答える