1

我正在尝试构建一个有限状态机,并且我想使用正则表达式检查我得到的序列。我需要检查序列是否来自以下形式:

例如:

"A,B,C,C,C,C,C,A"-> 被接受。

"A,B,C,C,C,C,A"-> 被忽略。

"A,B,C,C,C,C,C,C,A"-> 被忽略。

我找到了这篇文章和那篇文章,但我尝试的一切都不起作用。

我尝试了接下来的事情:A\B\D{5}\AABD{5}A还有更多,但再次没有成功。

编辑:我想知道 C 字符是否准确返回 5 次,前后都无关紧要,这意味着它也可能是这样的:

A,A,A,F,F,R,E,D,C,C,C,C,C,......

不要考虑逗号。

问题是我需要确定一个序列是否被接受,但是该序列来自下一种形式:A、B、C*10,我创建了机器类、状态类和事件类。但现在我需要知道我是否正好有 5 个 C 回报,这给我带来了很多问题。

编辑: 它不起作用,请参阅我添加的代码。

String sequence1 = "A,B,C,C,C,C,A";
String sequence2 = "A,B,C,C,C,C,C,A";
String sequence3 = "A,B,C,C,C,C,C,C,A";
Pattern mPattern = Pattern.compile("(\\w)(?:,\\1){4}");
Matcher m = mPattern.matcher(sequance1);
m.matches(); //FALSE
Matcher m = mPattern.matcher(sequance2);
m.matches(); //FALSE
Matcher m = mPattern.matcher(sequance3);
m.matches(); //FALSE

它总是返回错误的。

我怎样才能做到这一点?

谢谢。

4

2 回答 2

4

您的正则表达式不起作用,因为您没有考虑字符串中的逗号,我认为它是可用的。

您可以尝试以下正则表达式(我在这里发布了一个通用模式,您可以相应地对其进行修改):-

"(\\w)(?:,\\1){4}"

这将匹配用逗号分隔的任何 5 个相同字符序列。

\1用于反向引用第一个匹配的字符,其余4个字符应与此相同。

解释: -

"(         // 1st capture group
   \\w     // Start with a character
 )
 (?:       // Non-capturing group
    ,      // Match `,` after `C`
    \\1    // Backreference to 1st capture group. 
           // Match the same character as in (\\w)
 ){4}"     // Group close. Match 4 times 
           // As 1st one we have already matched in (\\w)

更新: -

如果您只想匹配5 length序列,您可以在第 5 次匹配后添加匹配字符的否定:-

"(\\w)(?:,\\1){4}(?!,\\1)"

(?!,\\1)-> 是否定的前瞻断言。它将匹配 5 个连续的字符,后面没有相同的字符。

更新: -

在上面的 Regex 中,我们还需要做一个\\1我们不能做的负面回顾。所以,我想出了这个看起来很奇怪的正则表达式。我自己不喜欢,但无论它是否有效,您都可以尝试:-

未测试:-

"(\\w),(^\\1)(?:,\\2){4}(?!,\\2)"

解释: -

(       // First Capture Group
  \\w   // Any character, before your required sequence. (e.g. `A` in `A,C,C,C,C,C`)
)       // Group end
,       // comma after `A`

(          // Captured group 2
   ^\\1    // Character other than the one in the first captured group. 
           // Since, We now want sequence of `C` after `A`
)
(?:        // non-capturing group
   ,       // Match comma
   \\2     // match the 2nd capture group character. Which is different from `A`, 
           // and same as the one in group 2, may be `C`

){4}       // Match 4 times

(?!        // Negative look-ahead
    ,
    \\2    // for the 2nd captured group, `C`
)

我不知道这种解释是否最有意义。但是你可以试试。如果它有效,而您无法理解,那么我将尝试解释得更好一些。

于 2012-11-09T12:20:43.043 回答
2

我不明白你尝试了什么,但你不需要转义字母来匹配它们。

我不确定您的要求是什么,但是要找到 5 个重复的字符,您可以使用它:

(\\p{L})(?:,\\1){4}

这将找到所有重复 5 次的字母。在 Regexr 上查看。

在我使用的 Regexr上,\w因为\p{L}那里不支持,但它在 Java 中。

\p{L}是一个 Unicode 属性,匹配任何语言中的每个字母。

  1. 这里的想法是匹配一个字母。这是由\\p{L}.

  2. 该字母存储在反向引用中,因为 . 周围有括号(\\p{L})

  3. 然后是非捕获组(?:,\\1)。这与逗号匹配,并且\\1是对之前捕获的字母的引用。

  4. 该非捕获组重复4次(?:,\\1){4}

==> 结果,此模式匹配 5 个相同的字母,中间有逗号。

这里的问题是,这个表达式将匹配至少 5 个相同的字母。如果它们更多,它也将(部分)匹配。

更新:

我看不到直接从正则表达式获得结果的机会。但这是一种间接获取长度的方法:

String[] TestInput = { "A,B,C,C,C,C,C", "A,B,C,C,C,C,C,D,E",
        "C,C,C,C,C", "C,C,C,C,C,D,E", "A,B,C,C,C,C", "C,C,C,C",
        "A,B,C,C,C,C,C,C,D,E", "C,C,C,C,C,C,D,E", "C,C,C,C,C,C" };

// Match at least 5 letters in a row
// The letter is in group 2
// The complete found sequence is in group 1
Pattern p = Pattern.compile("((\\p{L})(?:,\\2){4,})");

for (String t : TestInput) {
    Matcher m = p.matcher(t);
        if (m.find()) {

            // Get the length of the found sequence, after the commas has
            // been removed
            int letterLength = m.group(1).toString().replace(",", "")
                    .length();
            // Check your condition of exactly 5 equal letters
            if (letterLength == 5) {
                System.out.println(t + " ==> " + true);
            } else {
                System.out.println(t + " ==> " + false);
            }
        }else {
            System.out.println(t + " ==> " + false);
        }
}

输出:

A,B,C,C,C,C,C ==> 真
A,B,C,C,C,C,C,D,E ==> 真
C,C,C,C,C ==>真
C,C,C,C,C,D,E ==> 真
A,B,C,C,C,C ==> 假
C,C,C,C ==> 假
A,B,C, C,C,C,C,C,D,E ==> 错误
C,C,C,C,C,C,D,E ==> 错误
C,C,C,C,C,C ==>错误的

于 2012-11-09T12:20:42.350 回答