2012-03-09 12 views
5

Ho cercato di trovare la risposta al mio problema nella cronologia delle domande ma sono tornate indietro più di mille e dopo aver analizzato alcune decine di risposte corrispondenti su. Quindi ecco il mio problema.Java REGEX per abbinare un numero esatto di cifre in una stringa

Voglio essere in grado di trovare la prima sequenza di esattamente sei cifre in una stringa. Data la stringa "Qualche testo 987654321 e altro testo 123456 e altro testo di nuovo 654321 e altro testo alla fine" Voglio trovare la regex che corrisponderà alla sequenza 123456.

Sono nuovo di regex e una breve spiegazione su come funziona aiuterà molto.

Grazie in anticipo

+2

Il numero di sei cifre sarà sempre lo stesso? Sarà sempre separato da spazi? Potresti non aver bisogno di usare il Regex affatto se è così. Sono solo curioso perché non hai specificato la natura del numero di sei cifre. –

+0

Sono interessato a trovare una sequenza di esattamente 6 cifre, indipendentemente da quali siano. La sequenza può essere circondata da qualsiasi carattere, inclusi o non spazi. Quando dico qualsiasi cosa intendo è possibile avere caratteri UTF-8. In realtà la mia stringa cercata è in cinese tradizionale e non ho idea di cosa possa essere. È importante che se le sei cifre fanno parte di una sequenza con più di sei cifre che non produrrà alcuna corrispondenza. – Julian

+0

Non è quello che voglio. 987654 fa parte di una sequenza di più di 6 cifre (987654321) e voglio escluderlo. Grazie – Julian

risposta

11

È possibile utilizzare il modello (?<!\d)\d{6}(?!\d), che significa "una stringa di posizione che non è preceduta da una cifra, seguito da esattamente sei cifre; seguito da una stringa di posizioni che non è seguito di una cifra ". (La notazione (?<!...), noto come lookbehind negativo asserzione, significa "non preceduto da ...". La notazione (?!...), noto come lookahead negativo asserzione, significa "no con ...". La notazione \d significa una cifra. la notazione {n} significa "n tempi", in modo che ad esempio \d{6} significa "sei cifre")

quella potrebbe essere la seguente:.

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 versione precedente di questa risposta suggeriva l'uso di limiti di parole, \b; ma uno dei tuoi commenti suggerisce che le cifre potrebbero essere immediatamente precedute o seguite da caratteri del cinese tradizionale, che sono considerati caratteri di parole (e quindi non innescherebbero un limite di parole), quindi l'ho modificato.

+0

'\ w',' \ b', ... sono basati su ASCII in java (quindi il tuo '\ b' dovrebbe aver funzionato accidentalmente), puoi correggere questo comportamento da Java 7 usando la bandiera 'UNICODE_CHARACTER_CLASS', vedi [qui] (http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS) – stema

+0

@stema: In Java, anche se' \ w' è basato su ASCII per impostazione predefinita, '\ b' è basato su Unicode. (Non so perché.) – ruakh

1

La prima occorrenza di 6 cifre nella stringa inserita è in realtà 987654. Se vuoi dire la prima occorrenza di 6 cifre, circondato da personaggi che non sono cifre, allora questo dovrebbe funzionare:

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

EDIT: Questo approccio utilizza un lookbehind negativo e un lookahead negativo. E 'un po' diverso rispetto al metodo limite di parola in quanto corrisponderà 123456 nei seguenti stringhe

123456asdf some text hello 

another string a123456 aaaaaaaa 

Se i numeri saranno sempre circondato da spazi allora la parola approccio confine è probabilmente meglio.

+0

Nel mio esempio ho messo in chiaro cosa mi piacerebbe abbinare. Forse la domanda non era abbastanza chiara. Ma la tua regex ha funzionato. Grazie mille. – Julian

6

Il modello che stai cercando è:

(?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 

che sarà anche prendere le cose come

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 

Nel caso in cui si dispone di quelli di testo cinese.

+2

Molto bello: +1 per il supporto alla globalizzazione e non essere associato a spazi bianchi. –

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; 
} 

test con

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)); 
} 

uscita è

123456 
0

nella console JavaScript funziona questo. Attenzione per \\d:

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

r___ax145N 
Problemi correlati