Ich kann Dollarzeichen durch Matcher.quoteReplacement. ersetzen. Ich kann Wörter durch Hinzufügen von Begrenzungszeichen ersetzen:

from = "\\b" + from + "\\b"; 
outString = line.replaceAll(from, to);

Aber ich kann sie nicht kombinieren, um Wörter durch Dollarzeichen zu ersetzen.

Hier ist ein Beispiel. Ich versuche, "$temp4" (NICHT $temp40) durch "register1" zu ersetzen.

        String line = "add, $temp4, $temp40, 42";
        String to = "register1";
        String from = "$temp4";
        String outString;


        from = Matcher.quoteReplacement(from);
        from = "\\b" + from + "\\b";  //do whole word replacement

        outString = line.replaceAll(from, to);
        System.out.println(outString);

Ausgänge

"add, $temp4, $temp40, 42"

Wie kann ich $ temp4 und nur $ temp4 ersetzen?

7
john ktejik 18 Apr. 2018 im 02:16

4 Antworten

Beste Antwort

Verwenden Sie eindeutige Wortgrenzen (?<!\w) und (?!\w) anstelle von \b, die kontextabhängig sind:

from = "(?<!\\w)" + Pattern.quote(from) + "(?!\\w)";

Siehe die Regex-Demo .

Das (?<!\w) ist ein negatives Lookbehind, das die Übereinstimmung nicht besteht, wenn sich unmittelbar links vom aktuellen Speicherort ein Nicht-Wort-Zeichen befindet, und (?!\w) ist ein negatives Lookahead, das die Übereinstimmung nicht besteht, wenn es ein Nicht-Wort gibt. Wort char unmittelbar rechts vom aktuellen Standort. Das Pattern.quote(from) ist erforderlich, um Sonderzeichen in der Variablen from zu umgehen.

Siehe die Java-Demo:

String line = "add, $temp4, $temp40, 42";
String to = "register1";
String from = "$temp4";
String outString;

from = "(?<!\\w)" + Pattern.quote(from) + "(?!\\w)";

outString = line.replaceAll(from, to);
System.out.println(outString);
// => add, register1, $temp40, 42
4
Wiktor Stribiżew 17 Apr. 2018 im 23:32

Matcher.quoteReplacement() steht für die Ersatzzeichenfolge (to), nicht für den regulären Ausdruck (from). Verwenden Sie Pattern.quote(), um ein Zeichenfolgenliteral in den regulären Ausdruck aufzunehmen:

from = Pattern.quote(from);
1
shmosel 17 Apr. 2018 im 23:20

$ hat in Regex eine besondere Bedeutung (es bedeutet "Ende der Eingabe"). Um eine spezielle Bedeutung von Zeichen in Ihrem Ziel zu entfernen, wickeln Sie sie in Regex-Anführungszeichen \Q...\E ein. Da $ kein "Wort" -Zeichen ist, funktioniert die Wortgrenze nicht. Verwenden Sie stattdessen Umschauen:

line = line.replaceAll("(?<!\\S)\\Q" + from + "\\E(?![^ ,])", to);
1
Bohemian 18 Apr. 2018 im 05:12

Normalerweise ist Pattern.quote der Weg, um Zeichen zu entkommen, die von der Regex-Engine speziell interpretiert werden können.

Der reguläre Ausdruck ist jedoch immer noch falsch, da vor $ in line keine Wortgrenze steht. Leerzeichen und $ sind beide Nicht-Wort-Zeichen. Sie müssen die Wortgrenze nach dem Zeichen $ setzen. Hier ist Pattern.quote nicht erforderlich, da Sie selbst den Dingen entkommen.

String from = "\\$\\btemp4\\b";

Oder einfacher, weil Sie wissen, dass es bereits eine Wortgrenze zwischen $ und temp4 gibt:

String from = "\\$temp4\\b";

Die Variable from kann aus dem zu ersetzenden Ausdruck erstellt werden. Wenn from "$temp4" hat, können Sie dem Dollarzeichen entkommen und eine Wortgrenze hinzufügen.

from = "\\" + from + "\\b";

Ausgabe:

add, register1, $temp40, 42
0
rgettman 17 Apr. 2018 im 23:35