2009-02-08 30 views
34

Kann ein regulärer Ausdruck whitespace oder den Anfang eines Strings?Regulärer Ausdruck: Matchstart oder Leerzeichen

Ich versuche, Währung die Abkürzung GBP durch ein £ -Symbol zu ersetzen. Ich könnte einfach alles abgleichen, was mit GBP anfängt, aber ich möchte etwas konservativer sein und nach bestimmten Begrenzern suchen.

>>> import re 
>>> text = u'GBP 5 Off when you spend GBP75.00' 

>>> re.sub(ur'GBP([\W\d])', ur'£\g<1>', text) # matches GBP with any prefix 
u'\xa3 5 Off when you spend \xa375.00' 

>>> re.sub(ur'^GBP([\W\d])', ur'£\g<1>', text) # matches at start only 
u'\xa3 5 Off when you spend GBP75.00' 

>>> re.sub(ur'(\W)GBP([\W\d])', ur'\g<1>£\g<2>', text) # matches whitespace prefix only 
u'GBP 5 Off when you spend \xa375.00' 

Kann ich beide der letzteren Beispiele gleichzeitig durchführen?

+0

Welche Sprache ist das? Ist es Perl? –

+0

Python. –

+0

Ja Python, aber das Konzept ist immer gleich. – Mat

Antwort

38

Mit dem OR "|" Operator:

>>> re.sub(r'(^|\W)GBP([\W\d])', u'\g<1>£\g<2>', text) 
u'\xa3 5 Off when you spend \xa375.00' 
+1

Excellent. Ich war davon ausgegangen, dass ich gezwungen war, ganz am Anfang der Saite zu stehen. Geringfügige Änderung notwendig, um den Abstand beizubehalten: re (u '(^ | \ W) GBP ([\ W \ d])', u '\ g <1> £ \ g <2>', Text). Akzeptiert, weil es die intuitivste Lösung für mein unmittelbares Problem ist. – Mat

+0

@Mat: Danke, ich habe meine Antwort wie vorgeschlagen aktualisiert. –

24

\b ist Wortgrenze, die ein Leerraum, der Anfang einer Zeile oder ein nicht-alphanumerisches Symbol (\bGBP\b) sein kann.

+1

Kühl. Ich habe zwei Dinge aus deiner Antwort gelernt.1. Ich habe noch nie zuvor in regulären Ausdrücken Wortgrenzen verwendet. 2. Dinge (vor allem \ b) funktionieren nicht gut, wenn Sie versehentlich anstelle von r Präfixe in regulären Python-Ausdrücken verwenden. – Mat

+0

@Mat: Natürlich könnten Sie Ihre "myregex" – nosklo

+0

Cool verwenden. Das macht Sinn, wenn Sie es jetzt erwähnen. – Mat

1

Ja, warum nicht?

re.sub(u'^\W*GBP... 

entspricht dem Anfang der Zeichenfolge, 0 oder mehr Leerzeichen, dann GBP ...

bearbeiten: Oh, ich glaube, Sie Abwechslung wollen, verwenden Sie die |:

re.sub(u'(^|\W)GBP... 
0

Sie können führende und nachfolgende Leerzeichen aus dem Token immer vor der Suche zuschneiden, wenn es keine Übereinstimmungs-/Gruppierungssituation ist, die die vollständige Zeile erfordert.

6

Dies ersetzt GBP, wenn sie von Anfang an einer Schnur oder einem word boundary (das ist der Anfang einer Zeichenfolge bereits ist), und nach dem GBP kommt einen numerischen Wert oder eine Wortgrenze voraus ist:

re.sub(u'\bGBP(?=\b|\d)', u'£', text) 

Diese Entfernt die Notwendigkeit unnötiger Rückverweise durch Verwendung einer lookahead. Inklusive genug?

+0

"\ d +": das Pluszeichen ist nicht notwendig – tzot

+0

Sie haben Recht, in der Tat erlauben die meisten Regex-Motoren nicht für die Wiederholung oder und nur einige feste Wiederholung durch {MIN, MAX} innerhalb von Umblicken, die das \ d + ungültig machen. Ich war mir bewusst, aber komplett vermisst, also danke, ich habe entsprechend bearbeitet :) –

+0

@Martijn, das gilt nur für LookBEHINDs; lookAHEADs haben keine solche Beschränkung (zumindest nicht in irgendeinem Geschmack, mit dem ich vertraut bin). –

2

Ich glaube, Sie suchen '(^|\W)GBP([\W\d])'

0

Es funktioniert in Perl:

$text = 'GBP 5 off when you spend GBP75'; 
$text =~ s/(\W|^)GBP([\W\d])/$1\$$2/g; 
printf "$text\n"; 

Die Ausgabe lautet:

Beachten Sie, dass ich festlegte, dass die Übereinstimmung global sein sollte, um alle Vorkommen zu erhalten.

Verwandte Themen