Come dividere String con un separatore ma senza rimuovere quel separatore in Java?

Sto affrontando problemi nel dividere String .

Voglio dividere una String con un separatore ma senza perdere quel separatore.

Quando usiamo il somestring.split(String separator) in Java, divide la String ma rimuove la parte separatore da String . Non voglio che ciò accada.

Voglio risultato come di seguito:

 String string1="Ram-sita-laxman"; String seperator="-"; string1.split(seperator); 

Produzione:

 [Ram, sita, laxman] 

ma voglio il risultato come quello qui sotto invece:

 [Ram, -sita, -laxman] 

C’è un modo per ottenere risultati come questo?

 string1.split("(?=-)"); 

Funziona perché split realtà prende un’espressione regolare . Quello che stai vedendo in realtà è “lookahead positivo a larghezza zero”.

Mi piacerebbe spiegarti di più, ma mia figlia vuole fare una festa di tè. 🙂

Modifica: Indietro!

Per spiegare questo, prima ti mostrerò una diversa operazione di split :

 "Ram-sita-laxman".split(""); 

Questo divide la stringa su ogni stringa di lunghezza zero. C’è una stringa di lunghezza zero tra ogni personaggio. Pertanto, il risultato è:

 ["", "R", "a", "m", "-", "s", "i", "t", "a", "-", "l", "a", "x", "m", "a", "n"] 

Ora, modifico la mia espressione regolare ( "" ) in modo che corrisponda solo alle stringhe di lunghezza zero se sono seguite da un trattino .

 "Ram-sita-laxman".split("(?=-)"); ["Ram", "-sita", "-laxman"] 

In questo esempio, il ?= Significa “guarda avanti”. Più specificamente, significa “lookahead positivo “. Perché il “positivo”? Perché puoi anche avere un lookahead negativo ( ?! ) Che si dividerà su ogni stringa di lunghezza zero che non è seguita da un trattino:

 "Ram-sita-laxman".split("(?!-)"); ["", "R", "a", "m-", "s", "i", "t", "a-", "l", "a", "x", "m", "a", "n"] 

Puoi anche avere un lookbehind positivo ( ?< = ) Che dividerà su ogni stringa di lunghezza zero preceduta da un trattino:

 "Ram-sita-laxman".split("(?< =-)"); ["Ram-", "sita-", "laxman"] 

Infine, puoi anche avere un lookbehind negativo ( ?< ! ) Che si dividerà su ogni stringa di lunghezza zero che non è preceduta da un trattino:

 "Ram-sita-laxman".split("(?< !-)"); ["", "R", "a", "m", "-s", "i", "t", "a", "-l", "a", "x", "m", "a", "n"] 

Queste quattro espressioni sono conosciute collettivamente come espressioni di lookaround .

Bonus: metterli insieme

Volevo solo mostrare un esempio che ho incontrato di recente che combina due delle espressioni di ricerca. Supponi di voler dividere un identificatore di CapitalCase nei suoi token:

 "MyAwesomeClass" => ["My", "Awesome", "Class"] 

Puoi farlo usando questa espressione regolare:

 "MyAwesomeClass".split("(?< =[az])(?=[AZ])"); 

Questo si divide su ogni stringa di lunghezza zero preceduta da una lettera minuscola ( (?< =[az]) ) e seguita da una lettera maiuscola ( (?=[AZ]) ).

Questa tecnica funziona anche con gli identificatori di CamelCase.

È un po ‘rischioso, ma è ansible introdurre un separatore fittizio usando una funzione di sostituzione. Non conosco i metodi Java, ma in C # potrebbe essere qualcosa del tipo:

 string1.Replace("-", "#-").Split("#"); 

Ovviamente, dovresti scegliere un separatore fittizio che è garantito che non si trovi da nessun’altra parte nella stringa.

Un modo per farlo è dividere la stringa, quindi aggiungere il separatore all’inizio di ogni stringa estratta tranne la prima.

 seperator="-"; String[] splitstrings = string1.split(seperator); for(int i=1; i 

questo è il codice adatto alla risposta di LadaRaider.

Adam ha colpito l’unghia sulla testa! Ho usato la sua risposta per capire come inserire il nome del file dal browser della finestra di dialogo dei file in una casella di testo rich. Il problema che ho riscontrato è stato quando aggiungevo una nuova riga nella “\” nella stringa di file. Il comando string.split si stava dividendo in \ e cancellandolo. Dopo aver usato una combinazione del codice di Adam sono riuscito a creare una nuova riga dopo ogni \ nel nome del file.

Ecco il codice che ho usato:

 OpenFileDialog fd = new OpenFileDialog(); fd.Multiselect = true; fd.ShowDialog(); foreach (string filename in fd.FileNames) { string currentfiles = uxFiles.Text; string value = "\r\n" + filename; //This line allows the Regex command to split after each \ in the filename. string[] lines = Regex.Split(value, @"(?< =\\)"); foreach (string line in lines) { uxFiles.Text = uxFiles.Text + line + "\r\n"; } } 

Godere!

Walrusking