2010-01-18 9 views
42

Wie kann ich Zeichen in Java trimmen?
z.B.Zeichen in Java zuschneiden

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

j sollte

"joe \ jill"

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

j

sollte

„\ joe \ jill \“

etc

+0

Was sollte '\\\\ joe \ jill \\\\\\\\\\\\\\' zurückgeben? 'joe \\ jill' ?? – OscarRyz

+0

@Oscar ja. Wie die Trimmung in .net –

+10

Ich glaube nicht, dass diese Operation Trimmen genannt wird ... – Esko

Antwort

70

Apache Commons hat eine große StringUtils class. In StringUtils gibt es eine strip(String, String) Methode, die tun wird, was Sie wollen.

Ich empfehle sowieso Apache Commons, vor allem die Collections und Lang-Bibliotheken.

+0

Wirklich schöne Lösung. –

0

EDIT: Geändert durch Antwort nur die erste und letzte Zeichen '\' zu ersetzen.

0

Ich glaube nicht, dass es eine eingebaute Funktion zum Trimmen basierend auf einer übergebenen Zeichenfolge gibt. Hier ist ein kleines Beispiel, wie man das macht. Dies ist wahrscheinlich nicht die effizienteste Lösung, aber es ist wahrscheinlich schnell genug für die meisten Situationen, evaluieren und passen sich Ihren Bedürfnissen an. Ich empfehle, die Leistung zu testen und für jedes Code-Snippet zu optimieren, das regelmäßig verwendet wird. Im Folgenden habe ich einige Timing-Informationen als Beispiel angegeben.

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; 
} 

In dieser Antwort wird davon ausgegangen, dass die zu trimmenden Zeichen eine Zeichenfolge sind. Wenn beispielsweise "abc" übergeben wird, wird "abc" aber nicht "bbc" oder "cba" usw. ausgeschnitten.

Einige Leistungszeiten für die Ausführung der folgenden 10 Millionen Male.

" mile ".trim(); läuft in 248 ms als Referenzimplementierung für Leistungsvergleiche enthalten.

trim("smiles", "s"); läuft in 547 ms - etwa 2 mal so lang wie String.trim() Java-Methode.

"smiles".replaceAll("s$|^s",""); läuft in 12,306 ms - etwa 48 mal so lang wie Javas String.trim() Methode.

Und eine kompilierte RegexMuster Pattern pattern = Pattern.compile("s$|^s"); pattern.matcher("smiles").replaceAll(""); läuft in 7804 ms mit der Taste - etwa 31-mal so lang wie die Java String.trim() Methode.

+0

"answer.length - trimChar.length - 1" eigentlich –

+0

Nicht wirklich optimiert. Ich würde das nicht benutzen. – Pindatjuh

+0

warum nicht regex verwenden? –

0

Es scheint, dass es keine fertige Java API gibt, die das macht, aber Sie können eine Methode schreiben, um das für Sie zu tun. diese link könnte

+0

Regex ist die gebrauchsfertige API :-) –

+0

sicher ist es: D ich meinte eine Trim-Funktion, die String als die Frage sagt –

33

sehr nützlich sein, Das tut, was Sie wollen:

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

Die $ verwendet wird, um die Sequenz am Ende der Zeichenfolge zu entfernen. Die ^ wird verwendet, um im Anfang zu entfernen.

Als Alternative können Sie die Syntax verwenden:

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

Die | Mittel "oder".

Falls Sie andere Zeichen trimmen, passen nur die Regex:

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

Ich denke, Sie müssen die '\\', dh '" \\ hinzufügen y $ |^\\ x "' – EricG

1

Sie removeStart und removeEnd von Apache Commons Lang für die erste Option aus StringUtils

0

Hand benutzen könnte:

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); 
    } 
} 

Drucke

joe\jil

joe\jil

+2

umh .. ein Kommentar bitte auf dem Downvote? – OscarRyz

0

würde ich meine eigene kleine Funktion tatsächlich schreiben, funktioniert der Trick von plain old char Zugang:

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); 
} 

Dies auf ähnliche verhält, was String.trim() der Fall ist, nur dass es mit '\' statt mit Leerzeichen arbeitet.

Hier ist eine Alternative, die funktioniert und trim() verwendet. ;) Obwohl es nicht sehr effizient ist, wird es wahrscheinlich alle regexp-basierten Ansätze leistungsmäßig schlagen.

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

CharMatcher - Google Guava

In der Vergangenheit würde ich zweite Colins’ Apache commons-lang answer. Aber jetzt, dass Googles guava-libraries freigegeben wird, die CharMatcher Klasse wird tun, was Sie ganz schön wollen:

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

CharMatcher hat eine sehr einfache und leistungsfähige Reihe von APIs sowie einige vordefinierte Konstanten, die Manipulation machen sehr einfach. Zum Beispiel:

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"; 

Sehr nette Sachen.

+0

Sehen Sie sich den [CharMatcher] (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/base/CharMatcher.html) in Google Guava an. Glattes Zeug. Kluge Verwendung der Prädikatensyntax. Macht es einfach zu spezifizieren, welche der verschiedenen Definitionen von Whitespace-, Unsichtbar- und Kontrollzeichen Sie im Sinn haben. Das Dokument verweist auf eine interessante Tabelle mit einigen [verschiedenen Whitespace-Definitionen] (https://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ). –

0

So würde ich es machen.

Ich denke, es ist ungefähr so ​​effizient, wie es vernünftigerweise sein kann. Es optimiert die Groß- und Kleinschreibung und vermeidet das Erstellen mehrerer Teilzeichenfolgen für jede entfernte Untersequenz.

Beachten Sie, dass der Eckfall der Übergabe einer leeren Zeichenfolge an die Trimmung behandelt wird (einige der anderen Antworten würden in eine Endlosschleife gehen).

/** 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

Hier ist ein weiterer nicht-regexp, nicht super-genial, nicht super-optimiert, jedoch sehr leicht nicht-external-lib-Lösung zu verstehen:

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); 
} 

Verbrauch:

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; 
}