2010-01-18 4 views
42

Comment découper des caractères en Java?
par exemple.Garniture des caractères en Java

String j = “\joe\jill\”.Trim(new char[] {“\”}); 

j devrait être

"joe \ jill"

String j = “jack\joe\jill\”.Trim("jack"); 

j devrait être

« \ Joe \ jill \ »

etc

+0

Que devrait retourner '\\\\ joe \\ jill \\\\\'? 'joe \\ jill' ?? – OscarRyz

+0

@Oscar oui. Comme la garniture en .net –

+10

Je ne pense pas que cette opération s'appelle couper ... – Esko

Répondre

70

Apache Commons a un grand StringUtils class. Dans StringUtils il y a une méthode strip(String, String) qui fera ce que vous voulez.

Je recommande fortement d'utiliser Apache Commons de toute façon, en particulier les bibliothèques Collections et Lang.

+0

Vraiment belle solution. –

0

EDIT: Modifié par réponse à remplacer tout le premier et le dernier caractère '\'.

System.err.println("\\joe\\jill\\".replaceAll("^\\\\|\\\\$", "")); 
0

Je ne pense pas qu'il existe une fonction intégrée à couper en fonction d'une chaîne transmise. Voici un petit exemple de comment faire cela. Ce n'est probablement pas la solution la plus efficace, mais elle est probablement assez rapide pour la plupart des situations, évalue et s'adapte à vos besoins. Je recommande de tester les performances et d'optimiser au besoin tout extrait de code qui sera utilisé régulièrement. Ci-dessous, j'ai inclus quelques informations de synchronisation à titre d'exemple.

public String trim(String stringToTrim, String stringToRemove) 
{ 
    String answer = stringToTrim; 

    while(answer.startsWith(stringToRemove)) 
    { 
     answer = answer.substring(stringToRemove.length()); 
    } 

    while(answer.endsWith(stringToRemove)) 
    { 
     answer = answer.substring(0, answer.length() - stringToRemove.length()); 
    } 

    return answer; 
} 

Cette réponse suppose que les caractères à découper sont une chaîne. Par exemple, passer dans "abc" va couper "abc" mais pas "bbc" ou "cba", etc.

Quelques temps de performance pour exécuter chacun des 10 millions de fois suivants.

" mile ".trim(); s'exécute en 248 ms inclus comme implémentation de référence pour les comparaisons de performances.

trim("smiles", "s"); s'exécute en 547 ms - environ 2 fois plus longtemps que la méthode String.trim() de Java.

"smiles".replaceAll("s$|^s",""); fonctionne en 12306 ms - environ 48 fois plus long que la méthode String.trim() de Java.

Et en utilisant un modèle regex Pattern pattern = Pattern.compile("s$|^s"); pattern.matcher("smiles").replaceAll(""); des pistes en 7,804 ms compilé - environ 31 fois plus long que la méthode de java String.trim().

+0

"answer.length - trimChar.length - 1" réellement –

+0

Pas vraiment optimisé. Je n'utiliserais pas ça. – Pindatjuh

+0

pourquoi ne pas utiliser regex? –

0

Il semble qu'il n'y ait pas d'API Java prête à l'emploi qui fasse cela mais vous pouvez écrire une méthode pour le faire pour vous. ce link pourrait être utile

+0

Regex est l'api prêt à l'emploi :-) –

+0

sûr que c'est: D je voulais dire une fonction de trim qui prend la chaîne comme la question dit –

33

Cela fait ce que vous voulez:

public static void main (String[] args) { 
    String a = "\\joe\\jill\\"; 
    String b = a.replaceAll("\\\\$", "").replaceAll("^\\\\", ""); 
    System.out.println(b); 
} 

Le $ est utilisé pour éliminer la séquence en fin de chaîne. Le ^ est utilisé pour supprimer dans le début.

Comme alternative, vous pouvez utiliser la syntaxe:

String b = a.replaceAll("\\\\$|^\\\\", ""); 

Les | signifie "ou".

Si vous voulez couper d'autres caractères, adapter simplement l'expression rationnelle:

String b = a.replaceAll("y$|^x", ""); // will remove all the y from the end and x from the beggining 
+0

Je pense que vous devez ajouter le '\\', ie '" \\ y $ |^\\ x "' – EricG

1

Vous pouvez utiliser removeStart et removeEnd de Apache Commons Lang StringUtils

0

main pour la première option:

public class Rep { 
    public static void main(String [] args) { 
     System.out.println(trimChar('\\' , "\\\\\\joe\\jill\\\\\\\\") ) ; 
     System.out.println(trimChar('\\' , "joe\\jill") ) ; 
    } 
    private static String trimChar(char toTrim, String inString) { 
     int from = 0; 
     int to = inString.length(); 

     for(int i = 0 ; i < inString.length() ; i++) { 
      if(inString.charAt(i) != toTrim) { 
       from = i; 
       break; 
      } 
     } 
     for(int i = inString.length()-1 ; i >= 0 ; i--){ 
      if(inString.charAt(i) != toTrim){ 
       to = i; 
       break; 
      } 
     } 
     return inString.substring(from , to); 
    } 
} 

Imprime

joe\jil

joe\jil

+2

umh .. un commentaire s'il vous plaît sur le downvote? – OscarRyz

0

Je fait écrire ma propre petite fonction qui fait le tour en utilisant l'accès vieux char simple:

public static String trimBackslash(String str) 
{ 
    int len, left, right; 
    return str == null || (len = str.length()) == 0 
          || ((left = str.charAt(0) == '\\' ? 1 : 0) | 
      (right = len > left && str.charAt(len - 1) == '\\' ? 1 : 0)) == 0 
     ? str : str.substring(left, len - right); 
} 

Cette semblable à ce que se comporte String.trim() le fait, seulement que cela fonctionne avec '\' au lieu de l'espace.

Voici une alternative qui fonctionne et qui utilise effectivement trim(). ;) Althogh ce n'est pas très efficace, il va probablement battre toutes les approches basées sur la regexp performance sage.

String j = “\joe\jill\”; 
j = j.replace('\\', '\f').trim().replace('\f', '\\'); 
18

CharMatcher - Google Goyave

Dans le passé, je Colins’ Apache commons-lang answer deuxième. Mais maintenant que Google guava-libraries est libéré, la classe CharMatcher fera ce que vous voulez tout à fait bien:

String j = CharMatcher.is('\\').trimFrom("\\joe\\jill\\"); 
// j is now joe\jill 

CharMatcher a un ensemble très simple et puissant d'API ainsi que des constantes prédéfinies qui rendent la manipulation très facile. Par exemple:

CharMatcher.is(':').countIn("a:b:c"); // returns 2 
CharMatcher.isNot(':').countIn("a:b:c"); // returns 3 
CharMatcher.inRange('a', 'b').countIn("a:b:c"); // returns 2 
CharMatcher.DIGIT.retainFrom("a12b34"); // returns "1234" 
CharMatcher.ASCII.negate().removeFrom("a®¶b"); // returns "ab"; 

Très agréable.

+0

Consultez le [CharMatcher] (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/CharMatcher.html) dans Google Goyave. Slick stuff. Utilisation intelligente de la syntaxe Predicate. Facilite la définition des différentes définitions de caractères blancs, invisibles et de contrôle que vous avez en tête. Le document contient des liens vers une feuille de calcul intéressante répertoriant quelques [différentes définitions d'espaces] (https://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ). –

0

Voici comment je le ferais. Je pense que c'est à peu près aussi efficace que cela peut raisonnablement être. Il optimise le cas d'un seul caractère et évite de créer plusieurs sous-chaînes pour chaque sous-séquence supprimée.

Notez que le cas de passage d'une chaîne vide à couper est traité (certaines des autres réponses entreraient dans une boucle infinie).

/** Trim all occurrences of the string <code>rmvval</code> from the left and right of <code>src</code>. Note that <code>rmvval</code> constitutes an entire string which must match using <code>String.startsWith</code> and <code>String.endsWith</code>. */ 
static public String trim(String src, String rmvval) { 
    return trim(src,rmvval,rmvval,true); 
    } 

/** Trim all occurrences of the string <code>lftval</code> from the left and <code>rgtval</code> from the right of <code>src</code>. Note that the values to remove constitute strings which must match using <code>String.startsWith</code> and <code>String.endsWith</code>. */ 
static public String trim(String src, String lftval, String rgtval, boolean igncas) { 
    int         str=0,end=src.length(); 

    if(lftval.length()==1) {             // optimize for common use - trimming a single character from left 
     char chr=lftval.charAt(0); 
     while(str<end && src.charAt(str)==chr) { str++; } 
     } 
    else if(lftval.length()>1) {            // handle repeated removal of a specific character sequence from left 
     int vallen=lftval.length(),newstr; 
     while((newstr=(str+vallen))<=end && src.regionMatches(igncas,str,lftval,0,vallen)) { str=newstr; } 
     } 

    if(rgtval.length()==1) {             // optimize for common use - trimming a single character from right 
     char chr=rgtval.charAt(0); 
     while(str<end && src.charAt(end-1)==chr) { end--; } 
     } 
    else if(rgtval.length()>1) {            // handle repeated removal of a specific character sequence from right 
     int vallen=rgtval.length(),newend; 
     while(str<=(newend=(end-vallen)) && src.regionMatches(igncas,newend,rgtval,0,vallen)) { end=newend; } 
     } 

    if(str!=0 || end!=src.length()) { 
     if(str<end) { src=src.substring(str,end); }       // str is inclusive, end is exclusive 
     else  { src="";      } 
     } 

    return src; 
    } 
6

Voici une autre non-regexp, non-super-génial, non-super-optimisé, mais très facile à comprendre la solution-lib non externe:

public static String trimStringByString(String text, String trimBy) { 
    int beginIndex = 0; 
    int endIndex = text.length(); 

    while (text.substring(beginIndex, endIndex).startsWith(trimBy)) { 
     beginIndex += trimBy.length(); 
    } 

    while (text.substring(beginIndex, endIndex).endsWith(trimBy)) { 
     endIndex -= trimBy.length(); 
    } 

    return text.substring(beginIndex, endIndex); 
} 

Utilisation:

String trimmedString = trimStringByString(stringToTrim, "/"); 
0
public static String trim(String value, char c) { 

    if (c <= 32) return value.trim(); 

    int len = value.length(); 
    int st = 0; 
    char[] val = value.toCharArray(); /* avoid getfield opcode */ 

    while ((st < len) && (val[st] == c)) { 
     st++; 
    } 
    while ((st < len) && (val[len - 1] == c)) { 
     len--; 
    } 
    return ((st > 0) || (len < value.length())) ? value.substring(st, len) : value; 
} 
Questions connexes