regex - online - expresiones regulares javascript
¿Qué es un límite de palabras en expresiones regulares? (10)
Consulte la documentación sobre las condiciones de contorno:
http://java.sun.com/docs/books/tutorial/essential/regex/bounds.html
Mira esta muestra:
public static void main(final String[] args)
{
String x = "I found the value -12 in my string.";
System.err.println(Arrays.toString(x.split("//b-?//d+//b")));
}
Cuando lo imprima, observe que el resultado es el siguiente:
[Encontré el valor - en mi cadena]
Esto significa que el carácter "-" no se está recogiendo como estar en el límite de una palabra porque no se considera un carácter de palabra. Parece que @brianary me ganó un poco, así que recibe un voto positivo.
Estoy utilizando expresiones regulares de Java en Java 1.6 (inter alia para analizar la salida numérica) y no puedo encontrar una definición precisa de /b
("límite de palabras"). Había asumido que -12
sería una "palabra entera" (emparejada por /b/-?/d+/b
) pero parece que esto no funciona. Estaría agradecido de saber cómo se pueden combinar los números separados por espacios.
Ejemplo:
Pattern pattern = Pattern.compile("//s*//b//-?//d+//s*");
String plus = " 12 ";
System.out.println(""+pattern.matcher(plus).matches());
String minus = " -12 ";
System.out.println(""+pattern.matcher(minus).matches());
pattern = Pattern.compile("//s*//-?//d+//s*");
System.out.println(""+pattern.matcher(minus).matches());
Esto devuelve:
true
false
true
Creo que es el límite (es decir, el siguiente personaje) del último partido o el comienzo o el final de la cadena.
Creo que su problema se debe al hecho de que no es un personaje verbal. Por lo tanto, el límite de palabras coincidirá después de -
, y por lo tanto no lo capturará. Los límites de palabras coinciden antes que el primero y después de los últimos caracteres de una cadena, así como cualquier lugar donde antes sea un carácter de palabra o un carácter que no sea una palabra, y después es lo contrario. También tenga en cuenta que el límite de palabras es una coincidencia de ancho cero.
Una posible alternativa es
(?:(?:^|/s)-?)/d+/b
Esto coincidirá con cualquier número que comience con un carácter de espacio y un guión opcional, y que termine en un límite de palabra. También coincidirá con un número que comienza al comienzo de la cadena.
En el curso de aprender expresión regular, estaba realmente atrapado en el metacarácter que es /b
. De hecho, no comprendí su significado mientras me preguntaba " qué es, qué es " repetitivamente. Después de algunos intentos al usar el sitio web , observo los trazos verticales rosados al comienzo de las palabras y al final de las palabras. Lo entendí bien en ese momento. Ahora es exactamente la palabra ( /w
) -boundary .
Mi punto de vista es meramente orientado a la comprensión. La lógica detrás de esto debe ser examinada a partir de otras respuestas.
Hablo sobre los límites de expresiones regex estilo /b
-style que están here .
La historia corta es que son condicionales . Su comportamiento depende de lo que están próximos.
# same as using a /b before:
(?(?=/w) (?<!/w) | (?<!/W) )
# same as using a /b after:
(?(?<=/w) (?!/w) | (?!/W) )
A veces eso no es lo que quieres. Vea mi otra respuesta para la elaboración.
Me encontré con un problema aún peor al buscar texto para palabras como .NET
, C++
, C#
y C
Uno pensaría que los programadores de computadoras sabrían mejor que nombrar un idioma para el cual es difícil escribir expresiones regulares.
De todos modos, esto es lo que descubrí (resumido principalmente de http://www.regular-expressions.info , que es un gran sitio): en la mayoría de los sabores de expresiones regulares, los personajes que coinciden con la clase de caracteres de corta duración /w
son los personajes que son tratados como personajes de palabras por límites de palabras. Java es una excepción. Java admite Unicode para /b
pero no para /w
. (Estoy seguro de que había una buena razón para eso en ese momento).
El /w
significa "carácter de palabra". Siempre coincide con los caracteres ASCII [A-Za-z0-9_]
. Observe la inclusión del guión bajo y los dígitos (¡pero no el guión!). En la mayoría de los sabores que admiten Unicode, /w
incluye muchos caracteres de otros scripts. Hay mucha inconsistencia acerca de qué personajes están realmente incluidos. Por lo general, se incluyen letras y dígitos de scripts alfabéticos e ideogramas. La puntuación del conector que no sea el guión bajo y los símbolos numéricos que no son dígitos pueden o no estar incluidos. XML Schema y XPath incluso incluyen todos los símbolos en /w
. Pero Java, JavaScript y PCRE solo coinciden con los caracteres ASCII con /w
.
Esta es la razón por la que las expresiones regulares basadas en Java para C++
, C#
o .NET
(incluso cuando recuerda escaparse del período y las ventajas) están arruinadas por la /b
.
Nota: No estoy seguro de qué hacer con los errores en el texto, como cuando alguien no pone un espacio después de un punto al final de una oración. Lo permití, pero no estoy seguro de que sea necesariamente lo correcto.
De todos modos, en Java, si busca texto para esos idiomas con nombres extraños, debe reemplazar el /b
con antes y después de los designadores de espacios en blanco y puntuacion. Por ejemplo:
public static String grep(String regexp, String multiLineStringToSearch) {
String result = "";
String[] lines = multiLineStringToSearch.split("//n");
Pattern pattern = Pattern.compile(regexp);
for (String line : lines) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
result = result + "/n" + line;
}
}
return result.trim();
}
Luego en su prueba o función principal:
String beforeWord = "(//s|//.|//,|//!|//?|//(|//)|//'|///"|^)";
String afterWord = "(//s|//.|//,|//!|//?|//(|//)|//'|///"|$)";
text = "Programming in C, (C++) C#, Java, and .NET.";
System.out.println("text="+text);
// Here is where Java word boundaries do not work correctly on "cutesy" computer language names.
System.out.println("Bad word boundary can''t find because of Java: grep with word boundary for .NET="+ grep("//b//.NET//b", text));
System.out.println("Should find: grep exactly for .NET="+ grep(beforeWord+"//.NET"+afterWord, text));
System.out.println("Bad word boundary can''t find because of Java: grep with word boundary for C#="+ grep("//bC#//b", text));
System.out.println("Should find: grep exactly for C#="+ grep("C#"+afterWord, text));
System.out.println("Bad word boundary can''t find because of Java:grep with word boundary for C++="+ grep("//bC//+//+//b", text));
System.out.println("Should find: grep exactly for C++="+ grep(beforeWord+"C//+//+"+afterWord, text));
System.out.println("Should find: grep with word boundary for Java="+ grep("//bJava//b", text));
System.out.println("Should find: grep for case-insensitive java="+ grep("?i)//bjava//b", text));
System.out.println("Should find: grep with word boundary for C="+ grep("//bC//b", text)); // Works Ok for this example, but see below
// Because of the stupid too-short cutsey name, searches find stuff it shouldn''t.
text = "Worked on C&O (Chesapeake and Ohio) Canal when I was younger; more recently developed in Lisp.";
System.out.println("text="+text);
System.out.println("Bad word boundary because of C name: grep with word boundary for C="+ grep("//bC//b", text));
System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
// Make sure the first and last cases work OK.
text = "C is a language that should have been named differently.";
System.out.println("text="+text);
System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
text = "One language that should have been named differently is C";
System.out.println("text="+text);
System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
//Make sure we don''t get false positives
text = "The letter ''c'' can be hard as in Cat, or soft as in Cindy. Computer languages should not require disambiguation (e.g. Ruby, Python vs. Fortran, Hadoop)";
System.out.println("text="+text);
System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
PD ¡Mi agradecimiento a http://regexpal.com/ sin el cual el mundo regex sería muy miserable!
Un límite de palabras es una posición que está precedida por un carácter de palabra y no seguido por uno, ni seguido de un carácter de palabra y no precedido por uno.
Un límite de palabras puede ocurrir en una de tres posiciones:
- Antes del primer caracter en la cadena, si el primer caracter es un personaje de palabra.
- Después del último carácter en la cadena, si el último carácter es un carácter de palabra.
- Entre dos caracteres en la cadena, donde uno es un carácter de palabra y el otro no es un carácter de palabra.
Los caracteres de Word son alfanuméricos; un signo menos no es. Tomado de Regex Tutorial .
Un límite de palabras, en la mayoría de los dialectos de expresiones regulares, es una posición entre /w
/W
(char no de palabra), o al principio o al final de una cadena si comienza o termina (respectivamente) con un carácter de palabra ( [0-9A-Za-z_]
).
Por lo tanto, en la cadena "-12"
, coincidiría antes del 1 o después del 2. El guión no es un carácter de palabra.
cuando usa //b(//w+)+//b
que significa coincidencia exacta con una palabra que contiene solo caracteres de palabra ([a-zA-Z0-9])
en su caso, por ejemplo, al establecer //b
al comienzo de la expresión regular se acepta -12
(con espacio) pero nuevamente no se aceptará -12
(sin espacio)
como referencia para apoyar mis palabras: https://docs.oracle.com/javase/tutorial/essential/regex/bounds.html