Böyle bir şey ne istediğiniz olduğunu düşünüyorum.
Karakter için değişen:
(?=(.)(?!\1)(.))(?:\1\2){2,}
\0
, tüm değişken dizisi olacaktır, \1
ve \2
iki (ayrı) alternatif karakterlerdir.
N ve M karakter çalıştırmak için, muhtemelen (burada sayılarla M
N
olarak değiştirin ve) diğer karakterler ile ayrılır:
(?=(.))\1{N}.*?(?=(?!\1)(.))\2{M}
\0
infix dahil tüm maç olacak. \1
(en azından) N
kez \2
tekrar karakter (en azından) M
kez tekrar karakteridir.
Burada Java bir test koşum bulunuyor.
import java.util.regex.*;
public class Regex3 {
static String runNrunM(int N, int M) {
return "(?=(.))\\1{N}.*?(?=(?!\\1)(.))\\2{M}"
.replace("N", String.valueOf(N))
.replace("M", String.valueOf(M));
}
static void dumpMatches(String text, String pattern) {
Matcher m = Pattern.compile(pattern).matcher(text);
System.out.println(text + " <- " + pattern);
while (m.find()) {
System.out.println(" match");
for (int g = 0; g <= m.groupCount(); g++) {
System.out.format(" %d: [%s]%n", g, m.group(g));
}
}
}
public static void main(String[] args) {
String[] tests = {
"foobababababaf foobaafoobaaaooo",
"xxyyyy axxayyyya zzzzzzzzzzzzzz"
};
for (String test : tests) {
dumpMatches(test, "(?=(.)(?!\\1)(.))(?:\\1\\2){2,}");
}
for (String test : tests) {
dumpMatches(test, runNrunM(3, 3));
}
for (String test : tests) {
dumpMatches(test, runNrunM(2, 4));
}
}
}
Bu şu çıktıyı üretir:
foobababababaf foobaafoobaaaooo <- (?=(.)(?!\1)(.))(?:\1\2){2,}
match
0: [bababababa]
1: [b]
2: [a]
xxyyyy axxayyyya zzzzzzzzzzzzzz <- (?=(.)(?!\1)(.))(?:\1\2){2,}
foobababababaf foobaafoobaaaooo <- (?=(.))\1{3}.*?(?=(?!\1)(.))\2{3}
match
0: [aaaooo]
1: [a]
2: [o]
xxyyyy axxayyyya zzzzzzzzzzzzzz <- (?=(.))\1{3}.*?(?=(?!\1)(.))\2{3}
match
0: [yyyy axxayyyya zzz]
1: [y]
2: [z]
foobababababaf foobaafoobaaaooo <- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{4}
xxyyyy axxayyyya zzzzzzzzzzzzzz <- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{4}
match
0: [xxyyyy]
1: [x]
2: [y]
match
0: [xxayyyy]
1: [x]
2: [y]
Explanation
(?=(.)(?!\1)(.))(?:\1\2){2,}
has two parts
(?=(.)(?!\1)(.))
establishes \1
and \2
using lookahead
- İç içe negatif ileri yönlü olduğunu
\1
! = \2
sağlar
- Yakalama lookahead kullanma
\0
(yerine sadece "kuyruk" sonu) tüm maç var sağlar
(?:\1\2){2,}
, en az iki kere tekrar gerekir \1\2
sekans, yakalar.
(?=(.))\1{N}.*?(?=(?!\1)(.))\2{M}
has three parts
(?=(.))\1{N}
captures \1
in a lookahead, and then match it N
times
- Yakalama lookahead kullanarak tekrar
N
yerine N-1
olması anlamına gelir
.*?
bir infıx mümkün olduğunca kısa tutmak için isteksiz iki çalışır, ayrı sağlar
(?=(?!\1)(.))\2{M}
- Birinci parçasına benzer
- İç içe negatif ileri yönlü olduğunu
\1
! = \2
sağlar
Çalışma regex uzun çalışır maç olacak, örneğin, run(2,2)
maçlar "xxxyyy"
,
xxxyyy <- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{2}
match
0: [xxxyy]
1: [x]
2: [y]
Ayrıca, bu maçları üst üste izin vermez. Bu sadece bir run(2,3)
"xx11yyy222"
orada vardır.
xx11yyy222 <- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{3}
match
0: [xx11yyy]
1: [x]
2: [y]