J'ai String str
, à partir duquel je veux extraire la sous-chaîne en excluant un préfixe possible "abc"
.
La première solution qui me vient à l’esprit est la suivante:
if (str.startsWith("abc"))
return str.substring("abc".length());
return str;
Mes questions sont:
Existe-t-il une méthode plus "propre" pour le faire en utilisant split
et une expression régulière pour un "abc"
prefix?
Si oui, est-ce moins efficace que la méthode ci-dessus (parce qu'il cherche "tout au long" de la chaîne)?
Si oui, y a-t-il une meilleure façon de le faire (où "meilleure façon" = solution propre et efficace)?
Veuillez noter que le préfixe "abc"
peut apparaître ailleurs dans la chaîne et ne doit pas être supprimé.
Merci
Le code plus court que ci-dessus sera cette ligne:
return str.replaceFirst("^abc", "");
Mais en termes de performances, je suppose qu’il n’y aura pas de différence substantielle entre 2 codes. On utilise regex et on n'utilise pas regex mais recherche et sous-chaîne.
Utilisation de String.replaceFirst
avec ^abc
(pour faire correspondre la abc
principale)
"abcdef".replaceFirst("^abc", "") // => "def"
"123456".replaceFirst("^abc", "") // => "123456"
"123abc456".replaceFirst("^abc", "") // => "123abc456"
String#split
peut le faire, mais ce n’est pas une meilleure solution. En fait, ce sera vague et je ne recommanderais pas de l'utiliser à cette fin.startsWith
.String#startsWith
a été conçu pour cela.Vous pouvez facilement mesurer le temps nécessaire à l'exécution d'un code. Voici ce que vous pouvez faire:
Créez une grande boucle, à l'intérieur de celle-ci, vous pouvez en ajouter le compteur à une chaîne fictive afin de simuler les chaînes que vous souhaitez vérifier, puis essayez d'avoir startsWith
une fois et replaceAll
après:
for(int i = 0;i<900000;i++) {
StringBuilder sb = new StringBuilder("abc");
sb.append(i);
if(sb.toString().startsWith("abc")) { ... }
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~130
for(int i = 0;i<900000;i++){
StringBuilder sb = new StringBuilder("abc");
sb.append(i);
sb.toString().replaceAll("^abc", "");
}
long time = System.currentTimeMillis() - start;
System.out.println(time); //Prints ~730
Essaye ça
str = str.replaceAll("^abc", "");
Une solution sans regex (j'avais besoin de cela car la chaîne que je supprime est configurable et contient des barres obliques inverses, qui doivent être échappées pour une utilisation littérale dans une regex):
Apache Commons Lang StringUtils.removeStart(str, remove)
supprimera remove
du début de str
en utilisant String.startsWith
et String.substring
.
Le code source de la méthode est informatif:
public static String removeStart(final String str, final String remove) {
if (isEmpty(str) || isEmpty(remove)) {
return str;
}
if (str.startsWith(remove)){
return str.substring(remove.length());
}
return str;
}
Si les performances vous préoccupent, vous pouvez améliorer la solution str.replaceFirst("^abc", "")
en utilisant le même préfixe précompilé Pattern
pour faire correspondre plusieurs chaînes.
final Pattern prefix = Pattern.compile("^abc"); // Could be static constant etc
for ... {
final String result = prefix.matcher(str).replaceFirst("");
}
Je suppose que la différence sera perceptible si vous supprimez le même préfixe de nombreuses chaînes.