Diciamo che avete la seguente stringa:Sostituzione più sottostringhe in Java, quando il testo di sostituzione si sovrappone ricerca
cat dog fish dog fish cat
Si vuole sostituire tutti cats
con dogs
, tutte dogs
con fish
, e tutto fish
con cats
. Intuitivamente, il risultato atteso:
dog fish cat fish cat dog
Se si tenta la soluzione più ovvia, scorrendo con replaceAll()
, si ottiene:
- (originale)
cat dog fish dog fish cat
- (cat -> cane)
dog dog fish dog fish dog
- (cane -> pesce)
fish fish fish fish fish fish
- (pesce -> gatto)
cat cat cat cat cat cat
Chiaramente, questo non è il risultato previsto. Quindi qual è il modo più semplice per farlo? Posso mettere insieme qualcosa con Pattern
e Matcher
(e molto Pattern.quote()
e Matcher.quoteReplacement()
), ma mi rifiuto di credere che io sia la prima persona ad avere questo problema e che non ci sia alcuna funzione di libreria per risolverlo.
(FWIW, il caso attuale è un po 'più complicato e non comporta swap dritto.)
Questo sembra essere esplicitamente vietato, almeno in StringUtils 2.5 e precedenti: "Lanci: IllegalArgumentException - se la ricerca si ripete e c'è un ciclo infinito a causa di uscite di un essere entrate in un altro". (Anche se quello che ottengo effettivamente è un IllegalStateException in quanto la ricorsione non riesce a fermarsi correttamente.) –
Sono confuso. Il metodo che cito sopra (che ho copiato direttamente dai javadoc online) non esiste nemmeno. Non c'è nessun rimpiazzo con l'ultimo parametro booleano. D'altra parte 'StringUtils.replaceEach (" abcde ", new String [] {" ab "," cd "}, new String [] {" cd "," ab "})' restituisce '" cdabe "' che sembra per essere corretto. Ho controllato questo su 2.5 –
Ok, un po 'di chiarezza. 'replaceEachRepeatedly' lancia' IllegalStateException' come hai scritto tu. 'replaceEach' con l'ultimo parametro' boolean' non esiste. 'replaceEach' senza l'ultimo parametro' boolean' sembra fare il lavoro. –