Methoden "a.b".replaceAll(".", "$")

Natac

Bekanntes Mitglied
Das Problem ist schnell umschrieben: Ich habe einen beliebigen String [c]a[/c] in dem ich gerne einen beliebigen Teil-String [c]b[/c] durch eine ebenfalls beliebigen String [c]c[/c] ersetzt wird. Mein einfacher Ansatz:
Java:
a.replaceAll(b, c);

Wenn nun in [c]b[/c] allerdings Steuerzeichen enthalten sind, sollen diese ignoriert werden, also:
Java:
a.replaceAll(Pattern.quote(b), c);

Nun habe ich folgenden Sonderfall gefunden, wo auch das nicht funktioniert:

Java:
public static void main(final String[] args) {
  String a = "a.b";
  String b = ".";
  String c = "$";
  System.out.println(a.replaceAll(Pattern.quote(b), c));
}

Wenn ich das so durchlaufen lasse, dann bekomme ich folgende Exception:

Java:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
	at java.lang.String.charAt(Unknown Source)
	at java.util.regex.Matcher.appendReplacement(Unknown Source)
	at java.util.regex.Matcher.replaceAll(Unknown Source)
	at java.lang.String.replaceAll(Unknown Source)
	at Test.main(Test.java:28)

Verwende ich [c]"\\$"[/c] statt $ funktioniert es (Was mir natürlich nichts bringt, da ich nicht weiß welche Steuerzeichen es noch gibt und vom Nutzer nicht verlangen kann, dass er diese kennt und ein "\" davor schreibt).

Das dumme an der Geschichte: Sowohl
Code:
a
wie auch
Code:
b
und
Code:
c
sollen vollkommen willkürliche Strings sein, die der Nutzer eingeben kann.

Daher meine Frage: Wie schreibe ich die Zeile
Code:
"a.b".replaceAll(".", "$");
so, dass ich "a$b" erhalte!? (String c quoten ist auch nicht, da ich dann eine [c]java.lang.IllegalArgumentException: Illegal group reference[/c] erhalte. ;( )

Irgendwer eine Idee? :bahnhof:
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
Du bist Du auf ein interessantes Problem gestoßen. Ich habe mir den Quellcode von Matcher angeschaut. Das Problem tritt tatsächlich bei "$" im Replacementstrings auf. Abhilfe schafft "\\$". D.h., wen "$" im Replacementstring vorkommt, musst Du diesen Sonderfall abfangen. Alle anderen Replacementstrings müssten out of the Box funktionieren.

Ansonsten, wenn es tatsächlich nur um das Ersetzen von Literalen geht, ist bone2's Vorschlag sicher der beste.
 
S

SlaterB

Gast
das $ macht sich nicht so zum Spass zum Sonderzeichen,
sondern ist eine der wenigen, wenn nicht die einzige besondere Möglichkeit im Ersatz-String

'group reference' sagt ja schon die Fehlermeldung:
Java:
public class Test2
{
    public static void main(String[] args)
    {
        System.out.println("autoA aaaoA".replaceAll("(a..o)A", "$1B"));
    }
}
wird zu 'autoB aaaoB', man kann mehr selektieren als rausfliegt, Teile übernehmen, die Gruppen auch umsortieren, nur ergänzen ohne etwas zu löschen usw.
 

Natac

Bekanntes Mitglied
Java:
"a.b.c".replace(".","$")
kein regex, keine probleme
:toll: Das Leben kann so einfach sein. Aber wer nimmt schon nen "replace", wenn es ein "replaceAll" gibt ("replaceRegex" wäre passender gewesen, aber egal).

@SlaterB: Genau das wäre zu klären: Ist es nur "$", oder gibt es noch andere? Und wozu das $ im Ersatz-String da ist, ist auch klar, aber darum ging es ja gar nicht.
 
S

SlaterB

Gast
zumindest liefert
Java:
public class Test2 {
    public static void main(String[] args)  {
        for (int i = 0; i < 9999; i++)   {
            char c = (char)i;
            try    {
                "autoA aaaoA".replaceAll("(a..o)A", "" + c);
            }    catch (Exception e)     {
                System.out.println("Problem: " + c + ", " + i);
            }

        }
    }
}
nur
Code:
Problem: $, 36
Problem: \, 92

edit:
gibt der User zufällig \$ ein, also [c]\\$[/c], wäre es wiederum ungünstig, [c]\\\\$[/c] daraus zu machen ;)
aber wenn man beide Sonderzeichen ersetzt, kommt ja [c]\\\\\\$[/c] raus, das passt dann wieder
 
Zuletzt bearbeitet von einem Moderator:
N

nillehammer

Gast
Natac hat gesagt.:
@SlaterB: Genau das wäre zu klären: Ist es nur "$", oder gibt es noch andere?
Nein, es gibt nur das "$". Ein Blick in den Quellcode
Code:
java.util.regex.Matcher.replaceAll(Matcher.java:905)
zeigt das.
[EDIT]
Sorry, falsche Stelle aus dem Stacktrace rauskopiert. Der wichtige Teil des Quellcodes ist natürlich
Code:
java.util.regex.Matcher.appendReplacement(Matcher.java:771)
! Danke SlaterB
[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
S

SlaterB

Gast
@nillehammer
welchen Code meinst du genau?

in appendReplacement steht u.a.
Java:
        while (cursor < replacement.length()) {
            char nextChar = replacement.charAt(cursor);
            if (nextChar == '\\') {
                cursor++;
                nextChar = replacement.charAt(cursor);
                result.append(nextChar);
                cursor++;
            } else if (nextChar == '$') {
...

hier noch eine günstige Methode, quoteReplacement, siehe auch dessen Javadoc:
Java:
    /**
     * Returns a literal replacement <code>String</code> for the specified
     * <code>String</code>.
     *
     * This method produces a <code>String</code> that will work
     * use as a literal replacement <code>s</code> in the
     * <code>appendReplacement</code> method of the {@link Matcher} class.
     * The <code>String</code> produced will match the sequence of characters
     * in <code>s</code> treated as a literal sequence. Slashes ('\') and
     * dollar signs ('$') will be given no special meaning.
     *
     * @param  s The string to be literalized
     * @return  A literal string replacement
     * @since 1.5
     */
    public static String quoteReplacement(String s) {
        if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1))
            return s;
        StringBuffer sb = new StringBuffer();
        for (int i=0; i<s.length(); i++) {
            char c = s.charAt(i);
            if (c == '\\') {
                sb.append('\\'); sb.append('\\');
            } else if (c == '$') {
                sb.append('\\'); sb.append('$');
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Tommy Nightmare String.replaceAll(...) fehlerhaft? Allgemeine Java-Themen 3
N String.replaceAll Problem Allgemeine Java-Themen 5
K replaceAll bei sehr großen String Allgemeine Java-Themen 3
J replaceAll , "[", "]" & regex Allgemeine Java-Themen 12
Airwolf89 ReplaceAll, kann xml- Tag nicht aus String ausschneiden Allgemeine Java-Themen 3
A Probleme mit replaceAll Allgemeine Java-Themen 3
D replaceAll => no such java.lang.NoSuchMethodError Allgemeine Java-Themen 5
Daniel_L RegEx und replaceAll - Probleme mit escapen des Suchbegriffs Allgemeine Java-Themen 4
D Regex-Problem mit replaceAll Allgemeine Java-Themen 5
G String.replaceall - mehrere Zeichen durch eines ersetzen Allgemeine Java-Themen 5
S Geschwindigkeitsproblem bei String.replaceAll Allgemeine Java-Themen 2
Daniel_L Frage zu replaceAll und regulären Ausdrücken Allgemeine Java-Themen 15
T String.replaceAll - warum PatternSyntaxException? Allgemeine Java-Themen 4
F [ und mit replaceAll() ersetzen Allgemeine Java-Themen 2
G replaceAll() Allgemeine Java-Themen 4
@ String replaceAll(" ", ""); Allgemeine Java-Themen 2
T ReplaceAll (außer) Allgemeine Java-Themen 11
karambara ReplaceAll und Backslashes Allgemeine Java-Themen 3
P replaceAll und "\" durch "/" ersetzen Allgemeine Java-Themen 15
P ReplaceAll ersetzt nicht bzw. möchte verketteten string Allgemeine Java-Themen 4
G replaceAll Allgemeine Java-Themen 2
R String.replaceAll $lt; ersetzen Allgemeine Java-Themen 3
G ReplaceAll problem Allgemeine Java-Themen 7
P Alternative zu replaceAll (jdk < 1.4) Allgemeine Java-Themen 14

Ähnliche Java Themen

Neue Themen


Oben