2012-03-09 13 views
5

Traté de encontrar la respuesta a mi problema en el historial de preguntas, pero acaban regresando en más de mil y después de escanear algunas decenas de respuestas coincidentes, di arriba. Así que aquí está mi problema.Java REGEX para que coincida con un número exacto de dígitos en una cadena

Quiero ser capaz de encontrar la primera secuencia de exactamente seis dígitos en una cadena. Dada la cadena "Algunos texto 987654321 y algunos más texto 123456 y algún otro texto otra vez 654321 y más texto al final" Quiero encontrar la expresión regular que coincidirá con la secuencia 123456.

Soy nuevo en Regex y una breve explicación acerca de cómo funciona ayudará mucho.

gracias de antemano

+2

¿Será el número de seis dígitos siempre el mismo? ¿Siempre estará separado por espacios? Es posible que no necesite usar Regex si ese es el caso. Solo tengo curiosidad porque no especificó la naturaleza del número de seis dígitos. –

+0

Estoy interesado en encontrar una secuencia de exactamente 6 dígitos, independientemente de cuáles sean. La secuencia puede estar rodeada por cualquier carácter, incluidos o no espacios. Cuando digo algo me refiero a que es posible tener cualquier carácter UTF-8. En realidad, mi cadena buscada está en chino tradicional y no tengo idea de lo que puede ser. Es importante que si los seis dígitos son parte de una secuencia con más de seis dígitos, no produzcan ninguna coincidencia. – Julian

+0

Eso no es lo que quiero. 987654 es parte de una secuencia de más de 6 dígitos (987654321) y quiero excluirlo. Espero que aclare Gracias – Julian

Respuesta

11

Puede utilizar el patrón (?<!\d)\d{6}(?!\d), que significa "una posición de la cadena que no está precedido por un dígito, seguido de exactamente seis dígitos, seguido por una posición cadena que no vaya seguida por un dígito ". (La notación (?<!...), conocido como una aserción hacia atrás negativo , significa "no precedido por ...". La notación (?!...), conocido como una afirmación búsqueda negativa hacia delante , significa "no seguida de ...". La notación \d significa un dígito. la notación {n} significa " n veces", por lo que, por ejemplo \d{6} significa "seis dígitos")

que podría tener este aspecto:.

final String number; 
{ 
    final Matcher m = Pattern.compile("(?<!\\d)\\d{6}(?!\\d)").matcher(input); 
    if(m.find()) 
     number = m.group(); // retrieve the matched substring 
    else 
     number = null; // no match found 
} 

Nota: una versión anterior de esta respuesta sugería el uso de límites de palabras, \b; pero uno de sus comentarios sugiere que los dígitos podrían estar precedidos o seguidos inmediatamente por caracteres chinos tradicionales, que se consideran caracteres de palabras (y por lo tanto no desencadenarían un límite de palabras), así que lo he cambiado.

+0

'\ w',' \ b', ... están basados ​​en ASCII Java (por lo que su '\ b' debería haber funcionado accidentalmente), puede corregir este comportamiento desde Java 7 utilizando la bandera 'UNICODE_CHARACTER_CLASS', vea [aquí] (http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS) – stema

+0

@stema: En Java, aunque' \ w' está basado en ASCII por defecto, '\ b' está basado en Unicode. (No sé por qué.) – ruakh

1

La primera aparición de 6 dígitos en la cadena que ha publicado es realmente 987654. Si se refiere a la primera aparición de 6 dígitos rodeadas de caracteres que no sean dígitos, entonces esto debería funcionar:

(?<!\d)(\d{6})(?!\d) 

EDIT: Este enfoque utiliza un negativo de búsqueda hacia atrás y una búsqueda negativa hacia delante. Es un poco diferente que el enfoque de límite de palabra en el que coincidirá con 123456 en las siguientes cadenas

123456asdf some text hello 

another string a123456 aaaaaaaa 

Si los números siempre estará rodeado de espacios entonces la palabra enfoque límite es probablemente mejor.

+0

En mi ejemplo, dejé en claro lo que me gustaría hacer coincidir. Tal vez la pregunta no era del todo clara. Pero tu expresión regular funcionó. Muchas gracias. – Julian

6

El patrón que estás buscando es:

(?x)    # enable comments 
(?<! \p{Nd})  # no decimal number before 
\p{Nd} {6}  # exactly six repetitions of a decimal number 
(?!= \p{Nd})  # no decimal number after 

que también recoger cosas como

U+FF10 ‭ 0 FULLWIDTH DIGIT ZERO 
U+FF11 ‭ 1 FULLWIDTH DIGIT ONE 
U+FF12 ‭ 2 FULLWIDTH DIGIT TWO 
U+FF13 ‭ 3 FULLWIDTH DIGIT THREE 
U+FF14 ‭ 4 FULLWIDTH DIGIT FOUR 
U+FF15 ‭ 5 FULLWIDTH DIGIT FIVE 
U+FF16 ‭ 6 FULLWIDTH DIGIT SIX 
U+FF17 ‭ 7 FULLWIDTH DIGIT SEVEN 
U+FF18 ‭ 8 FULLWIDTH DIGIT EIGHT 
U+FF19 ‭ 9 FULLWIDTH DIGIT NINE 

En caso de que tenga los de texto en chino.

+2

Muy bonito: +1 para soporte de globalización y sin estar sujeto a espacios en blanco. –

1
public static String splitting(String str, int num){ 
    String arr[] = str.split("[^0-9]"); 
    for(String s:arr) 
     if(s.length() == num) 
      return s; 
    return null; 
} 

prueba con salida

public static void main(String[] args) { 
    String s = "Some text 987654321 and some more text 123456 and some other text again 654321 and more text in the end"; 
    System.out.println(splitting(s, 6)); 
} 

es

123456 
0

en la consola Javascript funciona esto. Tenga cuidado con \\d:

replacedString = "rx14ax145N".replace(RegExp("x14(?!\\d)", "g"), "___"); 

r___ax145N 
Cuestiones relacionadas