2010-12-16 13 views
11

Necesito coincidir cuando una cadena comienza con un número, luego sigue un punto, luego un espacio y 1 o más caracteres en mayúscula. La coincidencia debe ocurrir al comienzo de la cadena. Tengo la siguiente cadena.coincidencia de expresiones regulares de Java

1. PTYU fmmflksfkslfsm 

La expresión regular que he intentado con es:

^\d+[.]\s{1}[A-Z]+ 

Y no coincide. ¿Qué sería una expresión regular de trabajo para este problema?

+0

[Coincide conmigo] (http://regexpal.com/?flags=®ex=^\d%2B [.] \ S {1} [AZ]% 2B y entrada = 1.% 20PTYU% 20fmmflksfkslfsm) pero podría ser reescrito a '^ \ d + \.\ s [A-Z] + ' –

+2

' {1} 'es redundante: solo satura la expresión y puede (debería) eliminarse a favor de la claridad. –

+1

Lea acerca de Java y regex: http://www.regular-expressions.info/java.html. @AlexR y @codaddict tienen razón. Necesita usar '\\' en Java para crear uno '\'. –

Respuesta

26

(Lo siento por mi error anterior cerebro ahora firmemente comprometida Er, probablemente...)

Esto funciona:

String rex = "^\\d+\\.\\s\\p{Lu}+.*"; 

System.out.println("1. PTYU fmmflksfkslfsm".matches(rex)); 
// true 

System.out.println(". PTYU fmmflksfkslfsm".matches(rex)); 
// false, missing leading digit 

System.out.println("1.PTYU fmmflksfkslfsm".matches(rex)); 
// false, missing space after . 

System.out.println("1. xPTYU fmmflksfkslfsm".matches(rex)); 
// false, lower case letter before the upper case letters 

Descomponiéndola:

  • ^ = Start de la cadena
  • \d+ = Uno o más dígitos (el \ se escaparon porque está en una cadena, por lo tanto, \\)
  • \. = Un literal . (o el original [.] está muy bien) (de nuevo, se escapó en la cadena)
  • \s = Una carbón espacios en blanco (sin necesidad de que el {1} después de él) (voy a dejar de mencionar los escapes ahora)
  • \p{Lu}+ = Uno o más letras mayúsculas (utilizando el escape de Unicode adecuada   — gracias, tchrist, por señalar esto en tu comentario a continuación. En términos ingleses, el equivalente sería [A-Z]+)
  • .* = Algo más

Ver the documentation here para más detalles.

Sólo es necesario el .* al final si usted está utilizando un método como String#match (arriba), que tratará de igualar la entera cadena de .

+1

Es difícil saber si el OP está trabado con datos ASCII de 7 bits, o si lo necesita para trabajar con cualquier carácter Java, que son Unicode, no ASCII. Si esto último, por supuesto, necesita hacer ajustes. '\ p {Lu}' probablemente sea lo suficientemente bueno para letras mayúsculas, pero Java no ofrece una manera conveniente de hablar de espacios en blanco Unicode, por lo que debe escribir '[\ u000A- \ u002 \ u0085 \ u0085 \ u00A0 \ u1680 \ u180E \ u2000- \ u2028 \ u2029 \ u202F \ u205F \ u3000] ', como [He escrito en otro lugar] (http://stackoverflow.com/questions/4304928/unicode-equivalents-for-w-and-b-in -java-regular-expressions/4307261 # 4307261). – tchrist

+1

Uno realmente no debería decir que '[A-Z] +' coincide con "una o más letras mayúsculas", porque eso es lo que hace '\ p {Lu} +'. '[A-Z] +' simplemente coincide con uno o más (y prefiere más) de la A a la Z, lo que sostengo que es ligera pero significativamente diferente. Del mismo modo, '\ s' no es un carácter en blanco, sino uno de' [\ t \ n \ x0B \ f \ r] 'solamente. ¿Estoy siendo tan quisquilloso aquí? Trabajo en inmensos corpus de gigabytes de caracteres Unicode, pero * nunca * ASCII, todos los días usando Java y Perl, así que tal vez deba ser más cuidadoso que otros. ¿O tal vez no? – tchrist

+1

@tchrist: ** puntos muy, muy buenos ** No puedo creer que haya hecho algo tan centrado en el inglés. He marcado a otras personas por eso. ¡Mucho aprecio que me marques! –

1

Depende qué método se está utilizando. Creo que funcionará si usas Matcher.find(). No funcionará si usa Matcher.matches() porque la coincidencia funciona en línea completa. Si está utilizando los partidos() fijar el patrón de la siguiente manera:

^\d+\.\s{1}[A-Z]+.* 

(prestar atención en arrastrando .*)

Y también haría uso de \. en lugar de [.]. Es más legible

Cuestiones relacionadas