0

我正在研究一个正则表达式,我需要验证一个包含 4 个用逗号分隔的不同单词的输入文本。

输入文字单词: - 一、二、三、四。这些词中的每一个都不应重复一次以上。所以,它可以是:二、三、四、一或三、四、二、一而不是一、一、一、一

这是我写的,并通过单独搜索找到了部分解决方案

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

但是解决方案的问题是单词不断重复,“一,一,一,一”的测试失败了。

你能告诉我如何避免重复,我在哪里做错了吗?

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是零宽度。所以你不需要跟随它使用 a ?,你的意图可能是\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

您可以通过这种方式使用负前瞻(参见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最后)每个单词在匹配中只参与一次:)

于 2012-10-28T16:27:32.643 回答
0

为什么要使用正则表达式?

只需用逗号分割文本并进行通常的数组/列表重复检查

于 2012-10-28T15:49:18.450 回答
0

我相信您正在尝试使用正则表达式来解析非正则输入。在这种情况下,输入更像是一种上下文无关的语言。我建议对字符串进行标记并计数。

于 2012-10-28T15:50:28.357 回答