Pregunta

Estoy usando Java expresiones regulares en Java 1.6 (entre otras cosas para analizar salida numérica) y no puede encontrar una definición precisa de \b ( "límite de la palabra"). Yo había asumido que -12 sería una "palabra entera" (comparados por \b\-?\d+\b), pero parece que esto no funciona. Te agradecería saber sobre la manera de hacer coincidir los números separados por un espacio.

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
¿Fue útil?

Solución

A límite de palabra, en la mayoría de dialectos de expresiones regulares, es una posición entre \w y \W (char no-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 el "-12" cadena, sería coincide antes de la 1 o después de la 2. El guión no es un carácter de palabra.

Otros consejos

A límite de palabra puede ocurrir en una de tres posiciones:

  1. Antes del primer carácter de la cadena, si el primer carácter es un carácter de palabra.
  2. Después del último carácter de la cadena, si el último carácter es un carácter de palabra.
  3. Entre dos caracteres de la cadena, donde uno es un carácter de palabra y el otro no es un carácter de palabra.

caracteres de palabra son alfanumérico; un signo menos no lo es. Tomado de Regex Tutorial .

A límite de palabra es una posición que está ya sea precedido por un carácter de palabra y no con uno, o seguido por un carácter de palabra y no precedido por uno.

Me refiero a lo \b de estilo límites de expresiones regulares son en realidad aquí .

La historia corta es que son condicional . Su comportamiento depende de lo que están al lado.

# 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 desea. Ver mi otra respuesta para la elaboración.

Salida de la documentación de las condiciones de contorno:

http://java.sun.com/docs /books/tutorial/essential/regex/bounds.html

Mira este ejemplo:

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 se imprima, observe que la salida es la siguiente:

[encontré el valor -, en mi cadena.]

Esto significa que el carácter "-" no está siendo recogidos como en el límite de una palabra, ya que no se considera un carácter de palabra. Parece que @brianary un poco me ganó de mano, por lo que obtiene un up-voto.

Me encontré con un problema aún peor cuando la búsqueda de texto de palabras como .NET, C++, C# y C. Se podría pensar que los programadores informáticos sabrían mejor que por nombrar algo lenguaje que es difícil escribir expresiones regulares para.

De todos modos, esto es lo que he descubierto (que se resumen en su mayoría de http://www.regular-expressions.info , que es un gran sitio): En la mayoría de los sabores de expresiones regulares, los caracteres que se corresponden con la clase de caracteres \w corta a mano son los personajes que se tratan como caracteres de palabra por los límites de las palabras. Java es una excepción. Java soporta Unicode para \b pero no para \w. (Estoy seguro de que había una buena razón para ello en el momento).

El \w significa "carácter de palabra". Es siempre coincide con el [A-Za-z0-9_] caracteres ASCII. Nótese la inclusión del guión y los dígitos (pero no Dash!). En la mayoría de los sabores que soportan Unicode, \w incluye muchos personajes de otros scripts. Hay una gran cantidad de inconsistencia sobre la que los personajes son en realidad incluidos. Las letras y los dígitos de las escrituras alfabéticas y los ideogramas son generalmente incluidos. puntuacion conector que no sea el guión bajo y símbolos numéricos que son no pueden o no se pueden incluir dígitos. Esquema XML y XPath incluso incluyen todos los símbolos en \w. Pero partido de Java, JavaScript y PCRE sólo caracteres ASCII con \w.

¿Cuál es la razón por búsquedas de expresiones regulares basadas en Java para C++, C# o .NET (incluso cuando se recuerda a escapar del período y ventajas) están atornillados por el \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 frase. Se me permite por ello, pero no estoy seguro de que es necesariamente lo que hay que hacer.

De todos modos, en Java, si estás en busca de texto para las dichas lenguas extrañas-nombrado, es necesario sustituir la \b con espacios en blanco antes y después de puntuación y designadores. 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();
}

A continuación, 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));

P.S. Mi agradecimiento a http://regexpal.com/ sin el cual el mundo de expresiones regulares serían muy desgraciada!

En el curso de aprendizaje de la expresión regular, que era realmente atascado en el metacarácter que es \b. Yo a la verdad no comprendía su significado, mientras me preguntaba " lo que es, lo que es " repetitivamente. Después de algunos intentos de utilizar la página web , observo los guiones verticales de color rosa en el comienzo de cada palabras y al final de las palabras. Lo tengo bien su significado en ese momento. Ahora es exactamente palabra (\w) -CONTORNO .

Mi punto de vista es simplemente orientada comprensión inmensamente. La lógica detrás de ella debe ser examinada desde otras respuestas.

introducir descripción de la imagen aquí

Me gustaría explicar respuesta Alan Moore 's

  

A límite de palabra es una posición que está ya sea precedido por un carácter de palabra y no con uno, o seguido por un carácter de palabra y no precedido por uno.

Supongamos que tengo una cadena "Este es a c a camiseta y ella es a wesome", y se supone que debo reemplazar toda ocurrencia (s) de la letra 'a' sólo si esta carta existe en el "sitio limítrofe de una palabra" es decir, la letra a dentro de 'gato' no debe ser sustituido.

Así que voy realizo expresiones regulares (en Python ) como

re.sub("\ba","e", myString.strip()) // reemplazar a con e

so salida será Este es e c a t end ella es ewesome

Creo que su problema se debe al hecho de que - no es un carácter de palabra. Por lo tanto, el límite de palabra coincidirá después de la -, y por lo tanto no va a capturarlo. coinciden con los límites de palabra antes de la primera y después de los últimos caracteres de palabra en una cadena, así como cualquier lugar en el que antes de que sea un personaje de carácter de palabra o no palabra, y después de que es todo lo contrario. También tenga en cuenta que la frontera de palabra es un partido de ancho cero.

Una alternativa posible es

(?:(?:^|\s)-?)\d+\b

Esto corresponderá con cualquier número que comienzan con un carácter de espacio y un guión opcional, y que termina en un límite de palabra. También coincidirá con un número que comienza al principio de la cadena.

límite de palabra \ b se utiliza cuando una palabra debe ser un carácter de palabra y otra de carácter no-palabra. Expresión regular para número negativo debe ser

--?\b\d+\b

DEMO

Creo que es el límite (es decir, el carácter siguiente) del último partido o al principio o al final de la cadena.

cuando se utiliza \\b(\\w+)+\\b que significa coincidencia exacta con una palabra que sólo contiene caracteres de texto ([a-zA-Z0-9])

en su caso, para el establecimiento de \\b a principios de expresiones regulares aceptará -12 (con espacio) pero de nuevo no aceptará -12 (sin espacio) Ejemplo

de referencia para apoyar mis palabras: https: // docs. oracle.com/javase/tutorial/essential/regex/bounds.html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top