我正在尝试构建一个有限状态机,我想用正则表达式检查我得到的序列。 我需要检查序列是否来自以下形式:
例如:
"A,B,C,C,C,C,C,A"
- >被接受了。
"A,B,C,C,C,C,A"
- >被忽略了。
"A,B,C,C,C,C,C,C,A"
- >被忽略了。
我发现了这个post和post,但我尝试过的所有内容都无效。
我尝试了接下来的事情:A\B\D{5}\A
,ABD{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
它永远都是假的。
我怎样才能做到这一点?
感谢。
答案 0 :(得分: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`
)
我不知道这种解释是否最有意义。但你可以尝试一下。如果它有效,你无法理解,那么我会尝试更好地解释一下。
答案 1 :(得分:2)
我不明白你尝试了什么,但你不需要转义字母来匹配它们。
我不确定您的要求是什么,但要找到5个重复的字符,您可以使用它:
(\\p{L})(?:,\\1){4}
这会找到重复5次的所有字母。见here on Regexr。
在Regexr上我使用了\w
,因为那里不支持\p{L}
,但是它是用Java编写的。
\p{L}
是一个Unicode属性,匹配任何语言的每个字母。
这里的想法是匹配一封信。这是由\\p{L}
完成的。
此信件存储在反向引用中,因为(\\p{L})
周围有括号。
然后是非捕获组(?:,\\1)
。这与逗号匹配,\\1
是对之前捕获的字母的引用。
此非捕获组重复(?:,\\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 ==&gt;真正
A,B,C,C,C,C,C,D,E ==&gt;真正
C,C,C,C,C ==&gt;真正
C,C,C,C,C,D,E ==&gt;真正
A,B,C,C,C,C ==&gt;假
C,C,C,C ==&gt;假
A,B,C,C,C,C,C,C,D,E ==&gt;假
C,C,C,C,C,C,D,E ==&gt;假
C,C,C,C,C,C ==&gt;假的