Comment remplacer les cordes qu'une seule fois, sans regex en Java?
J'ai besoin de remplacer une dynamique sous-chaîne dans une chaîne plus longue, mais une seule fois (premier match). La classe String fournit seulement replace()
, qui remplace TOUTES les instances de la sous-chaîne; il y a un replaceFirst()
méthode, mais il ne faut regexp au lieu d'un régulier de la chaîne. J'ai deux problèmes avec l'aide de regex:
1) mon sous-chaîne est dynamique, donc peut contenir des caractères bizarres qui signifie quelque chose d'autre dans la regex, et je ne veux pas traiter avec le personnage s'échapper.
2) ce remplacement se produit très souvent, et je ne suis pas sûr qu'en utilisant les regex aura un impact sur les performances. Je ne peux pas compiler l'expression régulière à l'avance depuis la regex est lui-même dynamique!
Je dois être en manque de quelque chose ici, car il me semble que c'est un très basique chose... Est-il un replaceFirst méthode prenant régulièrement chaîne ailleurs dans le java franework?
- Votre deuxième préoccupation peut être valable, mais comme pour votre premier point: vous pouvez utiliser le Modèle.devis pour construire une regex qui va littéralement correspondent à une chaîne donnée. C'est, il va traiter avec le s'échapper pour vous.
Vous devez vous connecter pour publier un commentaire.
Utilisation
bigString.indexof(smallString)
pour obtenir l'index de la première occurrence de la petite chaîne dans le big one (ou -1 si aucun, dans ce cas, vous avez terminé). Ensuite, utilisezbigString.substring
pour obtenir les éléments de la chaîne de caractères avant et après le match, et enfinconcat
pour mettre ceux d'avant et d'après morceaux ensemble, avec votre remplacement prévus dans le milieu.Vous devez utiliser déjà testé et bien documentée des bibliothèques en faveur de la rédaction de votre propre code!
La
StringUtils
classe est de Apache Commons Lang3 paquet et peuvent être importés dans Maven comme ceci:Que Laurence a suggéré, vous pouvez utiliser
Pattern.quote
comme ceci:Cela crée un nouveau regex qui, littéralement, correspond à la sous-chaîne. Une autre approche est de simplement compiler la sous-chaîne de caractères littérales regex comme ceci:
Ce qui peut être légèrement plus efficace, mais aussi un peu moins clair.
Vous pouvez également le faire manuellement, puisque vous êtes seulement vouloir remplacer la première occurrence. Mais regexes sont assez efficaces, afin de ne pas optimiser prématurément!
assurez-vous également de remplacer
\s
et$s
dans le remplacement ainsi. C'est probablement ce que vous voulez parce que vous ne pouvez pas avoir tout sous-groupe avec les vôtres()
s'étant retiré).Classe StringBuilder en java peut être utilisé très facilement pour faire un non-regex en fonction de remplacement d'une chaîne de caractères par une autre.
Solution avec
Pattern
Vous pouvez également modifier le Chaîne de caractères.remplacer méthode qui utilise l' littérale interprétation de caractères à remplacer uniquement la première occurrence de la
target
séquence de caractères:À partir de la documentation de De modèle.LITTÉRAL:
Solution sans
Pattern
L'autre et de manière plus efficace, bien sûr, est d'utiliser Alex Martellis'astuce pour produire de la fonctionnalité suivante:
Mesure du temps
Sur la base de 10 pistes, la
replaceFirst2
méthode exécute sur 5 fois plus rapide que lereplaceFirst1
méthode. J'ai mis les deux de ces méthodes dans une boucle avec 100.000 répète et a obtenu les résultats suivants, en millisecondes:Modèle.citation ne semble pas fonctionner dans tous les cas. Essayez `Modèle.quote(":-)");