6

このような文字列があれば...

"123[1-5]553[4-52]63244[19-44]"

...次の条件を検証する最良の方法は何ですか:

  1. すべての開き括弧には対応する閉じ括弧があります
  2. 括弧は 3 セット以下です
  3. ネストされた括弧はありません(つまり、[123-[4]9])。

正規表現はこれらすべてのシナリオを検証できるでしょうか? そうでない場合、LINQ はどうですか?

4

3 に答える 3

9

ネストを許可しないため、正規表現を使用できます。

^([^[\]]*\[[^[\]]*\]){0,3}[^[\]]*$

説明:

  • (...){0,3}次の最大3セットに一致します。
    • [^[\]]*オプションの角かっこ以外の文字に一致します
    • \[[グループを開くために一致 します
    • [^[\]]*グループ内のオプションの角かっこ以外の文字に一致します
    • \]]グループを閉じるために一致します
  • 最後に、[^[\]]*すべてのグループの後で、より多くのオプションの非括弧文字に一致します
于 2013-02-22T20:40:09.543 に答える
5

これを行う最も速い方法は、文字列を反復することです

bool Validate(string input) 
{
    int braceBalance = 0;
    int openCount = 0;
    for (int i = 0; i < input.Length; i++)
    {
        if (input[i] == '[') 
        {
            braceBalance++;
            openCount++;
        }
        if (openCount > 3) return false;  // More than 3 pairs
        if (input[i] == ']') braceBalance--;
        // Check for nesting:
        if (braceBalance < -1 || braceBalance > 1) return false;
    }
    return (braceBalance == 0); // Check for equal number of opening and closing
}

RegEx と Linq の両方で、これよりも大きなオーバーヘッドが発生します (ただし、アプリケーションによっては問題にならない場合があります)。

于 2013-02-22T20:38:14.477 に答える
1

それがもっともらしいかどうかを確認するために、LINQ:y ソリューションを次に示します。

bool[] b =
  input.Where(c => c == '[' || c == ']')
  .Select((c,i) => (c == '[') == (i % 2 == 0))
  .ToArray();

bool valid = b.Length % 2 == 0 && b.Length <= 6 && b.All(i => i);

[との文字をフィルターで除外し、]交互の括弧 ( で始まる[)、偶数、およびそれらの数が 6 以下であることを確認します。

于 2013-02-22T21:09:30.263 に答える