正如其他回答所指出的那样,没有任何正则表达式可以做到你想要的,但是你说你想要学习正则表达式,因此这里有另一种可能会有帮助的元正则表达式方法。
以下是一个Java代码片段,给定一个字符串,程序会自动生成一个模式,匹配该字符串中长度为5的任何子字符串。
String seq = "ABCDEFGHIJKLMNOP";
System.out.printf("^(%s)$",
seq.replaceAll(
"(?=(.{5}).).",
"$1|"
)
);
输出结果为(
在 ideone.com 上可见):
^(ABCDE|BCDEF|CDEFG|DEFGH|EFGHI|FGHIJ|GHIJK|HIJKL|IJKLM|JKLMN|KLMNO|LMNOP)$
您可以使用此功能方便地生成正则表达式模式以匹配顺子扑克牌手,通过适当初始化
seq
。
它是如何工作的
.
元字符匹配“任何”字符(取决于我们所处的模式,换行符可能是一个例外)。
{5}
是精确的重复说明符。.{5}
精确匹配5个.
。
(?=…)
是正向先行断言;它断言给定的模式可以匹配,但由于它只是一个断言,它不会真正地(即消耗)从输入字符串中进行匹配。
简单的(…)
是一个捕获组。它创建了一个反向引用,您可以在模式中稍后使用,或在替换中使用,或者任何您认为合适的方式。
该模式在此处重复以方便使用:
match one char
at a time
|
(?=(.{5}).).
\_________/
must be able to see 6 chars ahead
(capture the first 5)
该模式逐个匹配一个字符
.
。在匹配该字符之前,我们使用断言
(?=…)
,断言我们可以看到6个字符
(.{5})
的总数,并将第一个
.{5}
捕获到组1中
(…)
。对于每个这样的匹配,我们使用
$1|
替换,即由组1捕获的任何内容,后跟交替元字符。让我们考虑当我们将其应用于较短的
String seq = "ABCDEFG";
时会发生什么。
↑
表示我们当前的位置。
=== INPUT === === OUTPUT ===
A B C D E F G ABCDE|BCDEFG
↑
We can assert (?=(.{5}).), matching ABCDEF
in the lookahead. ABCDE is captured.
We now match A, and replace with ABCDE|
A B C D E F G ABCDE|BCDEF|CDEFG
↑
We can assert (?=(.{5}).), matching BCDEFG
in the lookahead. BCDEF is captured.
We now match B, and replace with BCDEF|
A B C D E F G ABCDE|BCDEF|CDEFG
↑
Can't assert (?=(.{5}).), skip forward
A B C D E F G ABCDE|BCDEF|CDEFG
↑
Can't assert (?=(.{5}).), skip forward
A B C D E F G ABCDE|BCDEF|CDEFG
↑
Can't assert (?=(.{5}).), skip forward
:
:
A B C D E F G ABCDE|BCDEF|CDEFG
↑
Can't assert (?=(.{5}).), and we are at
the end of the string, so we're done.
所以我们得到了
ABCDE|BCDEF|CDEFG
,它们都是
seq
长度为5的子字符串。
参考资料: