Backslashes in regulären Python-Ausdrücken

8

Ich bin mit dem Backslash in regulären Ausdrücken verwechselt. Innerhalb einer Regex hat eine \ eine spezielle Bedeutung, z.B. \d bedeutet eine Dezimalziffer. Wenn Sie einen Backslash vor dem Backslash einfügen, geht diese spezielle Bedeutung verloren. Im regex-howto kann man lesen:

  

Das vielleicht wichtigste Metazeichen ist der Backslash, \ . Wie in Python-String-Literalen können dem Backslash verschiedene Zeichen folgen, um verschiedene spezielle Sequenzen zu signalisieren. Es wird auch verwendet, um alle Metazeichen zu umgehen, sodass Sie sie immer noch in Mustern zuordnen können. Wenn Sie beispielsweise eine [ oder \ anpassen möchten, können Sie ihnen einen umgekehrten Schrägstrich voranstellen, um ihre spezielle Bedeutung zu entfernen: \[ oder \ .

So print(re.search('\d', '\d')) gibt None , weil \d mit einer beliebigen Dezimalziffer übereinstimmt, aber keine in \d .

Ich würde jetzt erwarten, dass print(re.search('\d', '\d')) mit \d übereinstimmt, aber die Antwort ist immer noch None .

Nur print(re.search('\\d', '\d')) gibt als Ausgabe <_sre.SRE_Match object; span=(0, 2), match='\d'> .

Hat jemand eine Erklärung?

    
tobmei05 07.11.2015, 11:21
quelle

3 Antworten

8

Die Verwirrung beruht auf der Tatsache, dass der umgekehrte Schrägstrich \ als Escape auf zwei verschiedenen Ebenen verwendet wird. Zuerst führt der Python-Interpreter selbst Substitutionen für \ durch, bevor das re -Modul Ihre Zeichenfolge sieht. Zum Beispiel wird \n in ein Newline-Zeichen umgewandelt, \t wird in ein Tab-Zeichen umgewandelt usw. Um ein tatsächliches \ -Charakter zu erhalten, können Sie es ebenfalls umgehen, sodass \ ein einzelnes% co_de gibt % -Zeichen Wenn das Zeichen, das auf \ folgt, kein erkannter Escape-Zeichen ist, dann wird \ wie jedes andere Zeichen behandelt und weitergegeben, aber ich empfehle nicht, davon abhängig zu sein. Entkomme stattdessen immer deinen \ -Zeichen, indem du sie verdoppelst, d. H.% Co_de%.

Wenn Sie sehen möchten, wie Python Ihre Strings erweitert, drucken Sie einfach die Zeichenkette aus. Zum Beispiel:

%Vor%

Wenn \ Teil eines zusammengefassten Datentyps ist, z. eine Liste oder ein Tupel, und wenn Sie dieses Aggregat drucken, wird Python den String in einfache Anführungszeichen einschließen und die \ escapes (in einer kanonischen Form) enthalten, also achten Sie darauf, wie Ihre Zeichenkette gedruckt wird. Wenn Sie nur einen String in Anführungszeichen in den Interpreter eingeben, wird dieser in Anführungszeichen eingeschlossen mit '\' escapes angezeigt.

Sobald Sie wissen, wie Ihre Zeichenfolge codiert wird, können Sie sich überlegen, was das s -Modul damit tun wird. Wenn Sie zum Beispiel \ in einer Zeichenfolge, die Sie an das Modul re übergeben, verwerfen möchten, müssen Sie \ an re übergeben, was bedeutet, dass Sie in Ihrem zitierten Python \ verwenden müssen Zeichenfolge. Die Python-Zeichenfolge endet mit re und das \\ -Modul behandelt dies als einzelnes Literal \ -Zeichen.

Eine alternative Möglichkeit zum Einschließen von re -Zeichen in Python-Zeichenfolgen ist die Verwendung von Raw-Zeichenfolgen, z. \ entspricht \ .

    
Tom Karzes 07.11.2015, 11:54
quelle
4

Ein r-Zeichen vor dem regulären Ausdruck gibt in einem Aufruf von search () an, dass der reguläre Ausdruck eine rohe Zeichenfolge ist. Dadurch können umgekehrte Schrägstriche im regulären Ausdruck als reguläre Zeichen und nicht in einer Escape-Zeichenfolge verwendet werden. Lass es mich erklären ...

Bevor die Suchmethode des re-Moduls die an sie übergebenen Zeichenfolgen verarbeitet, nimmt der Python-Interpreter einen ersten Durchlauf über die Zeichenfolge vor. Wenn in einer Zeichenfolge Backslashes vorhanden sind, muss der Python-Interpreter entscheiden, ob jeder Bestandteil einer Python-Escape-Sequenz ist (z. B. \ n oder \ t) oder nicht.

Hinweis: An dieser Stelle ist Python egal, ob '\' ein Meta-Zeichen für reguläre Ausdrücke ist oder nicht.

Wenn auf das '\' ein erkanntes Python-Escapezeichen (t, n, usw.) folgt, werden der Backslash und das Escape-Zeichen durch das tatsächliche Unicode- oder 8-Bit-Zeichen ersetzt. Zum Beispiel würde "\ t" durch das ASCII-Zeichen für Tab ersetzt. Andernfalls wird es als '\' Zeichen übergeben und interpretiert.

Betrachten Sie Folgendes.

%Vor%

Manchmal möchten wir in eine Zeichenfolge eine Zeichenfolge einschließen, die '\' enthält, ohne dass sie von Python als Escape-Sequenz interpretiert wird. Um dies zu tun, entkommen wir dem '\' mit einem '\'. Wenn nun Python '\' sieht, ersetzt es die beiden umgekehrten Schrägstriche durch ein einzelnes '\' Zeichen.

%Vor%

Nachdem der Python-Interpreter beide Zeichenfolgen übergeben hat, werden sie an die Suchmethode des re-Moduls übergeben. Die Suchmethode analysiert die reguläre Ausdruckszeichenfolge, um die Metazeichen des regulären Ausdrucks zu identifizieren.

Nun ist '\' auch ein spezielles Meta-Zeichen für reguläre Ausdrücke und wird als ein interpretiert, sofern es zu dem Zeitpunkt, zu dem die re search () -Methode ausgeführt wird, nicht maskiert ist.

Betrachten Sie den folgenden Anruf.

%Vor%

Hier ist die Übereinstimmung Keine. Warum? Schauen wir uns die Strings an, nachdem der Python-Interpreter seinen Durchlauf gemacht hat.

%Vor%

Warum ist die Übereinstimmung gleich null? Wenn search () String 1 interpretiert, da es sich um einen regulären Ausdruck handelt, wird der Backslash als Metazeichen und nicht als gewöhnliches Zeichen interpretiert. Der umgekehrte Schrägstrich in String 2 hat jedoch keinen regulären Ausdruck und wurde bereits vom Python-Interpreter verarbeitet, sodass er als gewöhnliches Zeichen interpretiert wird.

Also sucht die search () Methode nach 'a escape-t' in der Zeichenkette 'a \ t', die keine Übereinstimmung ist.

Um das zu beheben, können wir der search () -Methode mitteilen, das '\' nicht als Metazeichen zu interpretieren. Wir können dies tun, indem wir entkommen.

Betrachten Sie den folgenden Anruf.

%Vor%

Schauen wir uns die Strings erneut an, nachdem der Python-Interpreter seinen Pass bestanden hat.

%Vor%

Wenn nun die search () -Methode den regulären Ausdruck verarbeitet, sieht sie, dass der zweite umgekehrte Schrägstrich von dem ersten zurückgestrichen wird und nicht als Meta-Zeichen betrachtet werden sollte. Es interpretiert daher die Zeichenfolge als 'a \ t', die String 2 entspricht.

Ein alternativer Weg, um bei der Suche () ein '\' als Zeichen zu betrachten, ist, ein r vor den regulären Ausdruck zu setzen. Dies sagt dem Python-Interpreter, dass er die Zeichenfolge NICHT vorverarbeitet.

Denken Sie darüber nach.

%Vor%

Hier ändert der Python-Interpreter nicht die erste Zeichenfolge, sondern die zweite Zeichenfolge. Die Strings, die an search () übergeben werden, sind:

%Vor%

Wie im vorherigen Beispiel interpretiert die Suche das '\' als einzelnes Zeichen '\' und nicht als Metazeichen, daher entspricht es String 2.

    
eric.mcgregor 21.04.2016 20:56
quelle
3

Pythons eigene String-Analyse (teilweise) kommt Ihnen in den Weg.

Wenn Sie sehen möchten, was re sieht, geben Sie

ein %Vor%

an der Python-Eingabeaufforderung. Sie sehen, dass \d und \d beide zu \d führen, wobei letzterer vom Python-String-Parser beachtet wird.

Wenn Sie keine Probleme damit haben möchten, verwenden Sie rohe Zeichenfolgen, wie in der Moduldokumentation vorgeschlagen >: r'\d' ergibt \d , das vom RE-Modul gesehen wird.

    
glglgl 07.11.2015 11:28
quelle

Tags und Links