2016-02-07 13 views
5

Ich habe einen regulären Ausdruck entwickelt, um einen XML-Block in einer Textdatei zu identifizieren. Der Ausdruck sieht wie folgt aus (ich alle Escape-java entfernt schlitzt es gut lesbar zu machen):Was ist der Unterschied zwischen [ s S] *? und .*? in Java reguläre Ausdrücke?

<\?xml\s+version="[\d\.]+"\s*\?>\s*<\s*rdf:RDF[^>]*>[\s\S]*?<\s*\/\s*rdf:RDF\s*> 

Dann optimiert ich es und ersetzt [\s\S]*? mit .*? Es die XML plötzlich erkennen gestoppt.

Soweit ich weiß, bedeutet \s alle white-space Symbole und \S bedeutet, dass alle nicht weiß beabstandeten Symbole oder [^\s] so [\s\S] sollte logisch äquivalent sein zu . ich nicht gierig Filter verwendet haben, so könnte, was der Unterschied sein ?

+3

Standardmäßig stimmt '.' nicht mit Zeilentrennzeichen überein.Es kann alle Zeichen (einschließlich Zeilentrennzeichen) übereinstimmen, wenn Sie das Flag "Patter.DOTALL" verwenden. '[\ s \ S]' wird gesetzt und enthält alle Leerzeichen \ s und alle Nicht-Leerzeichen \ S, die effektiv alle Zeichen (einschließlich Zeilentrennzeichen) darstellen. – Pshemo

+0

Das nachlaufende? trägt in beiden Fällen nichts bei. – EJP

+0

Eine sehr verwandte: [* Was ist der Unterschied zwischen diesen RegEx *] (http://StackOverflow.com/a/14648811/3832970) –

Antwort

6

Die Regex-Ausdrücke . und \s\S sind nicht gleichwertig, da . standardmäßig keine Zeilenabbrecher (wie neue Zeile) abfängt.

Nach dem oracle website Spieler .

ein beliebiges Zeichen (oder auch nicht Linienbegrenzer entsprechen)

während ein Leitungsabschluss eines der folgenden ist:

  • Ein Zeilenvorschubzeichen ('\n'),
  • Ein Wagenrücklaufzeichen, unmittelbar gefolgt von einem Zeilenende-Zeichen ("\r\n"),
  • Ein eigenständiges Wagenrücklaufzeichen ('\r'),
  • ein Next-Zeile-Zeichen ('\u0085'),
  • eine linien Separatorzeichen ('\u2028') oder
  • Ein Absatz-Trennzeichen ('\u2029).

Die beiden Ausdrücke sind nicht gleichwertig, solange die notwendigen Flags nicht gesetzt sind. Wieder unter Angabe der Oracle-Website:

Wenn UNIX_LINES Modus aktiviert ist, dann erkannten die einzige Linie Terminatoren Zeilenumbrüche sind.

Der reguläre Ausdruck . entspricht einem beliebigen Zeichen außer einer Zeile Terminator, sofern nicht das Flag DOTALL angegeben ist.

+1

Ja, das wird den Unterschied erklären, danke – Dmitry

2

Here ist ein Blatt, das alle Regex-Befehle erklärt.

Grundsätzlich wird \s\S alle Zeichen einschließlich Zeilenumbrüche übernehmen. Wobei . standardmäßig keine Abnahmeklemmen abgreift (bestimmte Flags müssen gesetzt sein, um sie aufzunehmen).

+0

Ja, jeder \ ist doppelt entkommen. Ich habe doppelte Schrägstriche entfernt, um es einfach zu lesen. Der Ausdruck funktioniert, hört jedoch auf zu arbeiten, sobald ich '[\ s \ S] *?' Durch '. *?' Ersetzt habe, so dass ein Unterschied vorhanden sein sollte. – Dmitry

+0

Dies ist ein echter Ausdruck: '<\\? Xml \\ s + version = \" [\\ d \\.] + \ "\ S * \\?> \\ s * <\\ s * rdf: RDF [^>] *> [\\ s \\ S] *? <\\ s * \\/s * rdf: RDF \\ s *> ' – Dmitry

+0

Das ist nicht wahr. '.' kann abhängig von bestimmten Flags neuen Zeilen entgehen. Werfen Sie einen Blick auf meine Antwort für alle Details .. –

Verwandte Themen