2010-09-21 15 views
7

Mit re in Python möchte ich alle Zeichen in einer Zeichenfolge, die dem ersten Auftreten eines Unterstrichs vorausgehen, zurückgeben. Außerdem möchte ich, dass die Zeichenfolge, die zurückgegeben wird, in Großbuchstaben und ohne keine nicht-alphanumerischen Zeichen ist.Zurückgeben aller Zeichen vor dem ersten Unterstrich

Zum Beispiel:

AG.av08_binloop_v6 = AGAV08 
TL.av1_binloopv2 = TLAV1 

Ich bin ziemlich sicher, dass ich weiß, wie eine Zeichenfolge in all string.upper() Groß mit zurückzukehren, aber ich bin sicher, es gibt mehr Möglichkeiten, um die . effizient zu entfernen. Jede Hilfe würde sehr geschätzt werden. Ich lerne immer noch regelmäßig Ausdrücke langsam aber sicher. Jeder Tipp wird zu meinen Notizen für zukünftige Verwendung hinzugefügt.

Um weiter zu klären, sind meine obigen Beispiele nicht die tatsächlichen Zeichenfolgen. Die tatsächliche Zeichenfolge würde wie folgt aussehen:

AG.av08_binloop_v6 

Mit meinem gewünschten Ausgang suchen, wie:

AGAV08 

Und das nächste Beispiel wäre das gleiche. String:

TL.av1_binloopv2 

gewünschte Ausgabe:

TLAV1 

Nochmals vielen Dank allen für die Hilfe!

Antwort

7

Versuchen Sie folgendes:

re.sub("[^A-Z\d]", "", re.search("^[^_]*", str).group(0).upper()) 
+0

+1 "on spec", sieht gut aus, aber ich bin kein Regex-Guru. Edit: Ich würde 're.search' durch' re.match' ersetzen und das erste '^' im Muster löschen ('match' beginnt immer am Anfang des Strings und ist dafür optimiert). – delnan

+0

Während ich die Einfachheit der anderen Antworten mag, wollte ich auch, mit welcher Lösung ich auch immer weiter experimentieren möchte. Dieser passt die Rechnung. Danke Gumbo! – durandal

+0

Nur für zukünftiges Wissen, wie würde dies mit '' re.compile'' geschehen? Ich mag den Einliner-Charakter, aber es wäre gut, für zukünftiges Wissen zu wissen. – durandal

19

Auch ohne re:

text.split('_', 1)[0].replace('.', '').upper() 
+1

ich persönlich diese besser lesbar und verständlich finden auf den ersten Blick und würde es daher vorziehen, dies in meiner Codebasis als die angenommene Antwort zu lesen. – HorseloverFat

2

Sie müssen nicht re für diese. Einfache String-Operationen würde genug sein, basierend auf Ihren Anforderungen:

tests = """ 
AG.av08_binloop_v6 = AGAV08 
TL.av1_binloopv2 = TLAV1 
""" 

for t in tests.splitlines(): 
    print t[:t.find('_')].replace('.', '').upper() 

# Returns: 
# AGAV08 
# TLAV1 

Oder wenn Sie müssen unbedingt verwenden re:

import re 

pat = r'([a-zA-Z0-9.]+)_.*' 
pat_re = re.compile(pat) 

for t in tests.splitlines(): 
    print re.sub(r'\.', '', pat_re.findall(t)[0]).upper() 

# Returns: 
# AGAV08 
# TLAV1 
+0

Während ich zustimme, dass Regexes Krebs nicht heilen und im Allgemeinen überstrapaziert werden, sind sie * eine brauchbare Wahl für Aufgaben wie diese. – delnan

+1

Lebensfähig, ja. Aber zu kompliziert für solch eine einfache Aufgabe. – jathanism

+0

Die Lösung von Gumbo ist ein gut lesbarer Oneliner. Wenn man die Grundlagen von Regex kennt, ist es völlig klar, was es tut. Es ist nicht so, dass es ein Monster mit 6.000 Zeichen ist. – delnan

1

import re

re .sub ("[^ AZ \ d]", "", yourstr.split ('_', 1) [0] .ober())

2

Da jeder seine Lieblings Implementierung zu geben, hier ist mir, die nicht re nicht verwendet:

>>> for s in ('AG.av08_binloop_v6', 'TL.av1_binloopv2'): 
...  print ''.join(c for c in s.split('_',1)[0] if c.isalnum()).upper() 
... 
AGAV08 
TLAV1 

Ich habe .upper() auf der Außenseite des Generators, so dass es nur einmal aufgerufen wird.

2

Er, nur zum Spaß, eine weitere Option Text vor dem ersten Unterstrich zu erhalten ist:

before_underscore, sep, after_underscore = str.partition('_') 

alle so in einer Linie sein könnte:

re.sub("[^A-Z\d]", "", str.partition('_')[0].upper()) 
Verwandte Themen