/ / Java regex intersection with backreference - java, regex

Intersección de expresiones regulares de Java con referencia inversa - java, expresiones regulares

Estoy tratando de crear una expresión regular en Java para que coincidael patrón de una palabra en particular para encontrar otras palabras con el mismo patrón. Por ejemplo, la palabra "diente" tiene el patrón 12213 ya que tanto la "t" como la "o" se repiten. Me gustaría que la expresión regular coincida con otras palabras como "dientes".

Así que aquí está mi intento de usar referencias inversas. En este ejemplo en particular, debería fallar si la segunda letra es la misma que la primera. Además, la última letra debe ser diferente de todas las demás.

String regex = "([a-z])([a-z&&[^1]])\2\1([a-z&&[^12]])";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher("tooth");

//This works as expected
assertTrue(m.matches());

m.reset("tooto");
//This should return false, but instead returns true
assertFalse(m.matches());

He verificado que funciona en ejemplos como "toot" si elimino el último grupo, es decir, lo siguiente, así que sé que las referencias están funcionando hasta este punto:

String regex = ([a-z])([a-z&&[^1]])\2\1";

Pero si vuelvo a agregar el último grupo al final del patrón, es como si ya no reconociera las referencias internas dentro de los corchetes.

¿Estoy haciendo algo mal o es un error?

Respuestas

4 para la respuesta № 1

Si imprime su expresión regular obtendrá una pista de lo que esmal, las referencias inversas en tus grupos en realidad son escapadas por Java para producir algunos caracteres extraños. Por lo tanto, no funciona como se esperaba. Por ejemplo:

m.reset("oooto");
System.out.println(m.matches());

tambien imprime

cierto

También, && no funciona en expresiones regulares, tendrá que usar mirar hacia el futuro en lugar. Esta expresión funciona para su ejemplo anterior:

String regex = "([a-z])(?!\1)([a-z])\2\1(?!(\1|\2))[a-z]";

La expresion (?!\1) mira hacia adelante para ver que el siguiente personaje no es el primero en la expresión, sin mover el cursor regex hacia adelante.


4 para la respuesta № 2

Prueba esto:

(?i)b(([a-z])(?!2)([a-z])32(?!3)[a-z]+)b

Explicación

(?i)           # Match the remainder of the regex with the options: case insensitive (i)
b             # Assert position at a word boundary
(              # Match the regular expression below and capture its match into backreference number 1
(              # Match the regular expression below and capture its match into backreference number 2
[a-z]          # Match a single character in the range between “a” and “z”
)
(?!            # Assert that it is impossible to match the regex below starting at this position (negative lookahead)
2             # Match the same text as most recently matched by capturing group number 2
)
(              # Match the regular expression below and capture its match into backreference number 3
[a-z]          # Match a single character in the range between “a” and “z”
)
3             # Match the same text as most recently matched by capturing group number 3
2             # Match the same text as most recently matched by capturing group number 2
(?!            # Assert that it is impossible to match the regex below starting at this position (negative lookahead)
3             # Match the same text as most recently matched by capturing group number 3
)
[a-z]          # Match a single character in the range between “a” and “z”
+              # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
b             # Assert position at a word boundary

Código

try {
Pattern regex = Pattern.compile("(?i)\b(([a-z])(?!\2)([a-z])\3\2(?!\3)[a-z]+)\b");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
for (int i = 1; i <= regexMatcher.groupCount(); i++) {
// matched text: regexMatcher.group(i)
// match start: regexMatcher.start(i)
// match end: regexMatcher.end(i)
}
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}

Verlo jugando aquí. Espero que esto ayude.