2013-06-13 15 views
9

Sto trovando questo abbastanza difficile da spiegare, quindi partirò con alcuni esempi di prima/dopo di ciò che mi piacerebbe ottenere.Dividere la stringa con "." (punto) durante la gestione delle abbreviazioni

Esempio di ingresso:

Hello.World

This.Is.A.Test

The.S.W.A.T.Team

S.W.A.T.

s.w.a.t.

2001.A.Space.Odyssey

uscita Ricercato:

Ciao Mondo

Questo è un test

La SWAT Team

SWAT

swat

2001 Odissea nello Spazio

In sostanza, mi piacerebbe creare qualcosa che sia in grado di suddividere stringhe da punti, ma allo stesso tempo gestisce abbreviazioni.

La mia definizione di un'abbreviazione è qualcosa che ha almeno due caratteri (involucro irrilevante) e due punti, ad esempio "A.B." o "a.b.". È non dovrebbe lavorare con cifre, ad esempio "1.a.".

Ho provato tutti i tipi di cose con regex, ma non è esattamente il mio forte seme, quindi spero che qualcuno qui abbia qualche idea o suggerimento che posso usare.

+5

Qual è la tua logica per determinare un'abbreviazione rispetto a una parola? In altre parole, puoi spiegare i criteri del tuo mondo reale per determinare questo? In particolare il tuo caso limite più grande è probabilmente intorno a parole di una sola lettera "A" e "I". –

+0

Mi dispiace, ho dimenticato di aggiungere quello. Appena aggiunto. –

+1

Vedo la tua definizione, ma mi chiedo se debba essere davvero l'inizio di lettera-punto-lettera-punto-punto '^ [AZ] \. [AZ] \.' O punto-lettera-punto-lettera-punto '\ . [AZ] \. [AZ] \. 'Le abbreviazioni devono essere maiuscole? –

risposta

11

Come rimuovere i punti che devono scomparire con espressioni regolari, quindi sostituire il resto dei punti con lo spazio? Regex può apparire come (?<=(^|[.])[\\S&&\\D])[.](?=[\\S&&\\D]([.]|$)).

String[] data = { 
     "Hello.World", 
     "This.Is.A.Test", 
     "The.S.W.A.T.Team", 
     "S.w.a.T.", 
     "S.w.a.T.1", 
     "2001.A.Space.Odyssey" }; 

for (String s : data) { 
    System.out.println(s.replaceAll(
      "(?<=(^|[.])[\\S&&\\D])[.](?=[\\S&&\\D]([.]|$))", "") 
      .replace('.', ' ')); 
} 

risultato

Hello World 
This Is A Test 
The SWAT Team 
SwaT 
SwaT 1 
2001 A Space Odyssey 

In regex ho bisogno di scappare significato speciale dei caratteri punti. Potrei farlo con \\. ma preferisco [.].

Quindi al galoppo di regex abbiamo il punto letterale. Ora questo punto è circondato da (?<=...) e (?=...). Queste sono parti del meccanismo look-around chiamato look-behind e look-ahead.

  • Da punti che devono essere rimossi hanno punti (o inizio dei dati ^) e alcuni non-white-space \\S che è anche non-cifre carattere \ D prima che io posso provarlo con (?<=(^|[.])[\\S&&\\D])[.].

  • dot inoltre che deve essere rimosso avere anche non-bianco-spazio e carattere non numerico e un altro punto (opzionalmente fine dei dati $) dopo di essa, che può essere scritto come [.](?=[\\S&&\\D]([.]|$))


A seconda delle esigenze [\\S&&\\D] che accanto alle lettere corrisponde anche a caratteri come [email protected]#$%^&*()-_=+... può essere sostituito con [a-zA-Z] per le sole lettere in inglese o \\p{IsAlphabetic} per tutte le lettere in Unicode.

+0

Perfetto! Ed è abbastanza vicino a quello che sono riuscito a inventare da solo. Devo lavorare sul mio regex :-) Grazie! –

+1

Ti dispiacerebbe spiegare la regex? Non riesco a trovare l'esatta funzionalità di

+0

Grazie! Ero abbastanza sicuro che fosse possibile farlo, ma non riuscivo a trovarlo documentato. Regex è fantastico! –

0

Poiché ogni parola inizia con una lettera maiuscola, suggerisco di rimuovere prima tutti i punti e sostituirla senza spazio (""). Quindi, scorrere tutti i caratteri e inserire lo spazio tra la lettera minuscola e la lettera maiuscola successiva. Inoltre, se incontri una lettera maiuscola con la seguente minuscola, metti lo spazio prima della maiuscola.

Funzionerà per tutti gli esempi forniti, ma non sono sicuro che ci siano eccezioni alla mia osservazione.

+0

Scusa, ho dimenticato di aggiungere che dovrebbe funzionare con caratteri sia maiuscoli che maiuscoli. Aggiunto ora. –

+0

Non è un problema. Fai una pre-elaborazione. Iterare su tutti i personaggi e inserire tutti i caratteri dopo il punto in maiuscolo. Rendi ogni altro in minuscolo. – darijan

Problemi correlati