296 votes

Différence entre String replace() et replaceAll()

Quelle est la différence entre les chaînes de caractères de java.lang.String. replace() y replaceAll() méthodes, autre que plus tard utilise regex ? Pour des substitutions simples comme, remplacer . avec / , y a-t-il une différence ?

232voto

emilan Points 2496

En java.lang.String le replace prend soit une paire de chars, soit une paire de CharSequence (dont String est une sous-classe, donc il prendra volontiers une paire de String). Le site replace remplacera toutes les occurrences d'un char ou d'un CharSequence . D'autre part, le premier String Les arguments de replaceFirst y replaceAll sont des expressions régulières (regex). L'utilisation de la mauvaise fonction peut entraîner des bogues subtils.

37 votes

De plus, selon la documentation java, chaque appel à str.replaceAll(regex, repl) est identique à Pattern.compile(regex).matcher(str).replaceAll(repl) . Il y a donc des frais généraux importants qui dépendent de l'utilisation qui en est faite.

8 votes

@user845279 C'est intéressant que vous disiez cela puisque String#replace(target, replacement) fait la même chose, sauf qu'il cite les chaînes de caractères : Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteRepla‌​cement(replacement.t‌​oString())); Y a-t-il une raison pour laquelle String#replace serait plus rapide que String#replaceAll ? Il ne semble pas que ce soit le cas puisque String#replace ne fait qu'effectuer des opérations supplémentaires.

2 votes

Par curiosité, dans cette réponse, où se trouve la comparaison explicite contre replaceAll . La réponse est plutôt replace

137voto

paulsm4 Points 39422

Q : Quelle est la différence entre le java.lang.String méthodes replace() y replaceAll() si ce n'est que ce dernier utilise des expressions rationnelles.

A : Juste le regex. Ils sont tous les deux remplacer tous :)

http://docs.oracle.com/javase/8/docs/api/java/lang/String.html

PS :

Il y a aussi un replaceFirst() (qui prend une regex)

4 votes

Merci d'avoir précisé qu'il s'agit uniquement de l'expression rationnelle. Comme j'aurais aimé qu'on l'appelle replaceWithRegex() au lieu de replaceAll().

0 votes

Clarification : replaceAll() fonctionne avec les expressions régulières, replace() fonctionne avec CharSequence

5 votes

@JohnnyFive Cela rend les choses plus confuses. L'expression régulière n'est pas un type, CharSequence est. Les deux sites replace() y replaceAll() "travailler avec CharSequence ". C'est que replaceAll() considère les CharSequence comme une expression régulière afin de rechercher correspondances regex alors que replace() considère les CharSequence comme un texte de recherche simple, de sorte qu'il recherche occurrences d'elle.

41voto

WickeD Points 728

Le site replace() est surchargée pour accepter à la fois une primitive char et un CharSequence comme arguments.

Maintenant, en ce qui concerne la performance, la replace() est un peu plus rapide que la méthode replaceAll() car cette dernière compile d'abord le motif regex, puis le fait correspondre avant de le remplacer, alors que la première correspond simplement à l'argument fourni et le remplace.

Puisque nous savons que le filtrage par regex est un peu plus complexe et par conséquent plus lent, alors préférer replace() sur replaceAll() est suggéré dans la mesure du possible.

Par exemple, pour des substitutions simples comme celles que vous avez mentionnées, il est préférable d'utiliser :

replace('.', '\\');

au lieu de :

replaceAll("\\.", "\\\\");

Remarque : les arguments de la méthode de conversion ci-dessus dépendent du système.

6 votes

Même remplacer fait la même chose, à partir de la documentation de java String : : public String replace(CharSequence target, CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())) ; }

1 votes

@Prateek : après jdk8, String::replace n'utilise plus Pattern : hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/ même dans jdk11.

0 votes

D'accord, en Java 8 En pratique, les deux méthodes sont presque le même, pour les deux apparaissent les Pattern.compile(...) contenu/partie dans leurs implémentations, semble replace est moins complexe sur la façon de définir/envoyer le premier argument. Il ne nécessite pas "\" . En outre, replace est disponible depuis Java 1.5 y replaceAll depuis 1.4

1voto

Erwinus Points 1587

Je sais que c'est un vieux sujet, mais je suis un peu nouveau dans le monde de Java et j'ai découvert une de ses particularités. J'ai utilisé String.replaceAll() mais obtenir des résultats imprévisibles.

Quelque chose comme ça perturbe la chaîne :

sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");

J'ai donc conçu cette fonction pour contourner ce problème étrange :

//String.replaceAll does not work OK, that's why this function is here
public String strReplace( String s1, String s2, String s ) 
{
    if((( s == null ) || (s.length() == 0 )) || (( s1 == null ) || (s1.length() == 0 )))
     { return s; }

   while( (s != null) && (s.indexOf( s1 ) >= 0) )
    { s = s.replace( s1, s2 ); }
  return s;
}

Ce qui vous rend capable de faire :

sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );

1 votes

String.replaceAll() s'attend à ce que expressions régulières et non des arguments littéraux, ce qui explique pourquoi vous obtenez des résultats "imprévisibles" (qui sont en réalité très prévisibles). String.replace() fonctionne comme vous le souhaitez.

1 votes

En règle générale, lorsque nous obtenons des résultats inattendus de Java, plutôt que de concevoir une nouvelle fonction pour les contourner, il est préférable de supposer que ces résultats sont tout à fait corrects et que nous comprenons mal la fonctionnalité Java que nous utilisons.

1 votes

Je comprends que replaceAll utilise une expression rationnelle, mais cette simple fonction strReplace a résolu mon problème.

-5voto

Pramod Kumar Points 3682

Replace fonctionne sur le type de données char mais replaceAll fonctionne sur le type de données String et les deux remplacent toutes les occurrences du premier argument par le second.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X