alphanummerische Zeichenfolge bearbeiten

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Franz.Luwein
User
Beiträge: 2
Registriert: Samstag 25. Juli 2015, 11:10

Hallo Python-Fachleute,

mein Programm zum rendern von Landkarten (Maperitive) kann mit Python-Scripten arbeiten.

Ein Muster dazu sieht so aus:

Code: Alles auswählen

def cycleLabel(e):
    str_list = []
    for set in e.tagSets:
        if set.hasTag('ref'):
            str_list.append(set['ref'])

    str_list.sort()
    return '+'.join(str_list)
Im 'ref'-Tag stehen z.B. die Namen von Autobahnen, Bundes-, Landes und Kreisstraßen.
Also z.B. A 7, A 45a, B 254, L 3161, K 74 usw.

Mein Ziel ist es, sg. Labels auf der Karte mit diesem Text zu beschriften.

Problem:
Bei den Autobahnen und den Bundesstraßen muss das "A" bzw. "B" entfernt werden.
Bei Landes- und Kreisstraßen sind die Buchstaben "L" und "K" erwünscht/notwendig.

Bitte verratet mir, wie ein Python-Script aussieht, das das kann.

Excel kann ich, da ist das recht einfach.
=WENN(ODER(LINKS(A2;1)="A";LINKS(A2;1)="B");ERSETZEN(A2;1;2;"");A2)
Das nützt mir jedoch nicht.
Von python habe ich null Ahnung.

Mit freundlichem Gruß

Franz Luwein
Zuletzt geändert von Anonymous am Samstag 25. Juli 2015, 23:10, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

das geht z.B. mit der sub Methode aus dem `re` (Regular Expression) Modul.

Beispiel:

Code: Alles auswählen

>>> import re
>>> a = ['A7', 'K9', 'B255', 'L123']
>>> for i in a:
...     re.sub('^[A-Z]', '', i)
... 
'7'
'9'
'255'
'123'
>>> 
Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@noisefloor: Es sollen aber wohl nur Bezeichnungen geändert werden, die mit "A" oder "B" anfangen. Man könnte dies auch mit Python-Boardmitteln lösen. Leider bietet die `replace()`-Methode für Strings keine Möglichkeit an, eine Oder-Verknüpfung anzugeben (`startswith()` und `endswith()` lösen das mit einem Tupel). Daher würde ich wohl auch zu regulären Ausdrücken greifen, aber eben etwas spezialisierter:

Code: Alles auswählen

import re

labels = ['A 7', 'A 45a', 'B 254', 'L 3161', 'K 74']
for label in labels:
    print(re.sub('^[AB][ ]*', '', label))
Äquivalenter Python-Code:

Code: Alles auswählen

for label in labels:
    if label.startswith(('A', 'B')):
        label = label.replace('A', '', 1).replace('B', '', 1)
        print(label.lstrip())
Oder einfach (auch näher am Excel-Code):

Code: Alles auswählen

for label in labels:
    if label.startswith(('A', 'B')):
        label = label[2:]
    print(label)
Wenn es also möglichst flexibel hinsichtlich der Leerzeichen (keins, eins oder beliebig viele) nach dem Präfix sein soll, dann würde ich Möglichkeit 1 vorschlagen. Falls das Muster garantiert immer "Präfix Suffix" ist (also immer exakt 1 Leerzeichen zwischen den beiden Teilen steht), dann würde ich Möglichkeit 3 vorschlagen, da die relativ schwierig zu lesende Regex-Syntax dann IMHO keinen entscheidenden Mehrwert bringt.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@snafu: das stimmt - aber ich wollte noch Raum für kreative Eigenleitung lassen ;-)

Gruß, noisefloor
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Oder wenn man nochmal drüber nachdenkt, dann geht auch schlichtweg:

Code: Alles auswählen

for label in labels:
    if label.startswith(('A', 'B')):
        label = label[1:].lstrip()
    print(label)
Dies macht die Nutzung eines regulären Ausdrucks unnötig und schafft trotzdem die Flexibilität hinsichtlich möglicher Leerzeichen.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

noisefloor hat geschrieben:@snafu: das stimmt - aber ich wollte noch Raum für kreative Eigenleitung lassen ;-)
Außerdem kommt ein regulärer Ausdruck ja auch ohne Strings als Zwischenenschritte aus. Dies spart mutmaßlich nochmal 7-8 Nanosekunden ein und verbessert somit die Performance. ;)
Franz.Luwein
User
Beiträge: 2
Registriert: Samstag 25. Juli 2015, 11:10

Hallo ihr Zwei,

es war offensichtlich eine gute Idee in diesem Forum zu fragen.
Danke für Euere Hilfe.
Wenn ich das wider Erwarten nicht zum Laufen bekomme, melde ich mich noch einmal.

Übrigens: Das mit dem "Raum für eigene Kreativität lassen" ist im Prinzip/Grundsätzlich eine sinnvolle Vorgehensweise. Aber ...

Ein schönes Wochenende wünscht

Franz Luwein
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Natürlich kann man das auch einfacher und ohne reguläre Ausdrücke lösen:

Code: Alles auswählen

label = label.lstrip('ABLK ')
mcdwerner
User
Beiträge: 113
Registriert: Donnerstag 7. Juli 2011, 14:27

@Sirius3: "L" und "K" sollten stehen bleiben, ausserdem könnte es sein (???) dass der Name einer Autobahn zufälligerweise auch mit "A" beginnt (z.B. "A A17"), dein Code würde das 2. "A" auch löschen
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mcdwerner hat geschrieben:ausserdem könnte es sein (???) dass der Name einer Autobahn zufälligerweise auch mit "A" beginnt (z.B. "A A17")
Habe ich allerdings noch nie irgendwo gesehen. Beim Parsen bestimmter Muster sollte man natürlich einerseits alle Eventualitäten mit einplanen, aber andererseits auch realitätsnah bleiben.

Ich finde den Vorschlag von Sirius3 gar nicht mal so schlecht. Mir war schlichtweg nicht bekannt, dass `strip()` bei Übergabe einer Zeichenkette die Zeichen einzeln interpretiert, sonst hätte ich es vermutlich selbst vorgeschlagen. Es ist IMHO eine etwas unglückliche API, aber nun gut...
Antworten