正则表达式匹配包含非重复单词的字符串

时间:2012-10-28 15:44:49

标签: java regex groovy

我正在处理一个正则表达式,我需要验证一个包含由逗号分隔的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

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

您能告诉我如何避免重复吗?我在哪里犯错?

6 个答案:

答案 0 :(得分:1)

使用单个正则表达式来解决这个特定问题要容易得多。

首先,\b为零宽度。因此,您无需使用?关注它,您的意图可能是\s?

接下来,在一般情况下,正则表达式几乎是无状态的,这意味着您需要按如下方式构造正则表达式。

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

如您所见,您必须手动处理组合爆炸。这远远不够理想。

您应该在,上拆分并使用java进行检查。

  

感谢您的回复。从我的理解,你希望我不使用正则表达式而不是使用java.can你详细了解如何检查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
}

答案 1 :(得分:1)

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

应该没有正则表达式

答案 2 :(得分:0)

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

只需在逗号上拆分文本,然后执行常用的数组/列表重复检查

答案 3 :(得分:0)

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

答案 4 :(得分: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

答案 5 :(得分: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一起)每个单词在比赛中只参加一次:)