0

コンマで区切られた4つの異なる単語を含む入力テキストを検証する必要がある正規表現に取り組んでいます。

入力テキストの単語: - 1、2、3、4。これらの単語はそれぞれ、複数回繰り返されるべきではありません。したがって、次のようになります: 2、3、4、1 または 3、4、2、1、1 ではなく、1、1、1

これが私が書いたもので、別々の検索を行うことで部分的な解決策を見つけました

^\b(one|two|three|four)\b?,\b(one|two|three|four)\b?,\b(one|two|three|four)\b?,\b(one|two|three|four)\b

しかし、ソリューションの問題は、単語が繰り返され、「1、1、1、1」のテストが失敗することです。

重複を避ける方法と、どこで間違いを犯しているのか教えてください。

4

6 に答える 6

1
boolean valid( String input ) {
  input.tokenize( ',' ).with { list ->
    list.unique( false ) == list &&
      list.every { it in ['one','two','three','four'] }
  }
}

正規表現なしで行う必要があります

于 2012-10-28T16:06:47.363 に答える
1

単一の正規表現でこの特定の問題を解決しない方がはるかに簡単です。

まず、\bゼロ幅です。したがって、 を使用してそれに従う必要はありません。?意図はおそらく\s?です。

次に、一般的なケースでは、正規表現はほとんどステートレスです。つまり、次のように正規表現を作成する必要があります。

^\s*(one\s*,(two\s*,(three\s*,four|four\s*,three)|three\s*,(two\s*,four|four\s*,two)...

ご覧のとおり、組み合わせ爆発を手動で処理する必要があります。これは理想とはかけ離れています。

代わりに、分割し,て Java を使用して確認する必要があります。

返信ありがとうございます。私が理解していることから、正規表現を使用するのではなく、Java を使用することを望んでいます。Java をチェックインする方法について少し詳しく教えてください

これを試してください(テストされていないコードはバグになります):

public parseList(String input) {
  String[] numbers = { "one", "two", "three", "four" };
  bool foundNumbers = { false, false, false, false };
  String delims = "\s*,";
  String[] tokens = input.split(delims);

  if (tokens.length != 4) {
    //deal with error case as you wish
  }

  for (int i = 0; i < numbers.length; ++i) {
    for (int j = 0; j < tokens.length; ++j) {
      if (numbers[i].equals(tokens[j])) {
        if (!foundNumbers[i]) {
          foundNumbers[i] = true;
        } else {
          //deal with error case as you wish
        }
      }
    }
  }

  for (int i = 0; i < foundNumbers.length; ++i) {
    if (!foundNumbers[i]) {
      //deal with error case as you wish
    }
  }

  //success
}
于 2012-10-28T15:51:33.183 に答える
0

なぜ正規表現を使いたいのですか?

テキストをコンマで分割し、通常の配列/リストの重複チェックを実行するだけです

于 2012-10-28T15:49:18.450 に答える
0

正規表現を使用して非正規の入力を解析しようとしていると思います。この場合、入力は文脈自由言語に似ています。文字列をトークン化してカウントすることをお勧めします。

于 2012-10-28T15:50:28.357 に答える
0

この方法で否定先読みを使用できます ( Regexrを参照)。

\b(one|two|three|four)\b,             # match one of the allowed words
\b(?!\1)(one|two|three|four)\b,       # match one of them but not first matched one
\b(?!\1|\2)(one|two|three|four)\b,    # match one of them but not first and second matched ones
\b(?!\1|\2|\3)(one|two|three|four)\b  # match one of them but not first, second and third matched ones
于 2012-10-28T16:04:49.133 に答える
0

これには絶対に正規表現を使用しないでください。ただし、次のことができます。

boolean foundMatch = subjectString.matches(
    "(?x)                            # Verbose regex                        \n" +
    "(?:                             # Match...                             \n" +
    " (?:one()|two()|three()|four()) #  one of the four words               \n" +
    " (?:\\s*,\\s*|\\s*$)            #  a comma or end-of-string            \n" +
    "){4}                            # four times                           \n" +
    "$                               # End of string                        \n" +
    "\\1\\2\\3\\4                    # Assert that all four words have matched");

空のキャプチャ グループは、(最後に一緒に\1\2\3\4) 各単語が一致に 1 回だけ参加することを保証します :)

于 2012-10-28T16:27:32.643 に答える