15 Stimmen

Regulärer Ausdruck, der nur auf uneingeschriebene Sonderzeichen passt

Ich versuche, einen regulären Ausdruck zu finden, der nur auf Zeichen passt, denen keine spezielle Escape-Sequenz in einer Zeichenkette vorausgeht.

Zum Beispiel in der Zeichenfolge Is ? stranded//? möchte ich die Möglichkeit haben, die ? die nicht mit einer anderen Zeichenkette escaped wurde, so dass ich dieses Ergebnis erhalten kann: **Is Dave stranded?**

Aber ich habe beim besten Willen keine Möglichkeit gefunden, einen Weg zu finden. Ich habe nur reguläre Ausdrücke gefunden, die alle ersetzbaren Zeichen auffressen.

Wie konstruiert man einen regulären Ausdruck, der nur auf Zeichen passt, denen keine Escape-Sequenz vorausgeht?

5voto

Buh Buh Punkte 7281

Verwenden Sie einen negativen Rückblick, dafür wurden sie entwickelt!

(?<!//)[?]

Um es aufzuschlüsseln:

(
    ?<!    #The negative look behind.  It will check that the following slashes do not exist.
    //     #The slashes you are trying to avoid.
)
[\?]       #Your special charactor list.

Nur wenn das // nicht gefunden wird, wird die Suche fortgesetzt.

Ich denke, in Java wird es wieder als eine Zeichenfolge etwas wie escaped werden müssen:

Pattern p = Pattern.compile("(?<!//)[\\?]");

4voto

anubhava Punkte 713155

Probieren Sie diesen Java-Code aus:

str="Is ? stranded//?";
Pattern p = Pattern.compile("(?<!//)([?])");
m = p.matcher(str);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    m.appendReplacement(sb, m.group(1).replace("?", "Dave"));
}
m.appendTail(sb);
String s = sb.toString().replace("//", "");
System.out.println("Output: " + s);

OUTPUT

Output: Is Dave stranded?

2voto

Buh Buh Punkte 7281

Ich habe darüber nachgedacht und habe eine zweite, einfachere Lösung gefunden, die Regexe vermeidet. Die anderen Antworten sind wahrscheinlich besser, aber ich dachte, ich könnte es trotzdem posten.

String input = "Is ? stranded//?"; 
String output = input
    .replace("//?", "a717efbc-84a9-46bf-b1be-8a9fb714fce8")
    .replace("?", "Dave")
    .replace("a717efbc-84a9-46bf-b1be-8a9fb714fce8", "?");

Schützen Sie einfach das "//?", indem Sie es durch etwas Eindeutiges (z. B. eine guid) ersetzen. Dann wissen Sie, dass alle verbleibenden Fragezeichen Freiwild sind.

1voto

Brian Clapper Punkte 24335

Gruppierung verwenden. Hier ist ein Beispiel:

import java.util.regex.*;

class Test {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("([^/][^/])(\\?)");
        String s = "Is ? stranded//?";
        Matcher m = p.matcher(s);
        if (m.matches)
            s = m.replaceAll("$1XXX").replace("//", "");
        System.out.println(s + " -> " + s);
    }
}

Ausgabe:

$ java Test
Is ? stranded//? -> Is XXX stranded?

In diesem Beispiel bin ich:

  • indem Sie zunächst alle nicht ausgeschriebenen ? durch "XXX" ersetzen,
  • dann werden die "//"-Escape-Sequenzen entfernt.

EDIT Verwenden Sie if (m.matches) um sicherzustellen, dass Sie nicht übereinstimmende Zeichenfolgen richtig behandeln.

Dies ist nur ein einfaches Beispiel. Sie müssen es natürlich noch ausbauen, um es robuster zu machen. Aber es bringt die allgemeine Idee rüber.

0voto

Borealid Punkte 90999

Übereinstimmung mit einer Reihe von Zeichen, die KEINE Escape-Sequenz sind, dann ein Regex-Sonderzeichen. Sie könnten eine invertierte Zeichenklasse verwenden ( [^/] ) für das erste Stück. Sonderfall ein nicht abgeschirmtes Regex-Zeichen am Anfang der Zeichenkette.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X