preg_replace -> python

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
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

Code: Alles auswählen

<?php
$zeichenkette = 'Wort-Haus „Katze“';

$suchmuster[0] = '/-/';
$suchmuster[1] = '/„/';
$suchmuster[2] = '/“/';

$ersetzungen[0] = ' ';
$ersetzungen[1] = ' ';
$ersetzungen[2] = ' ';

echo preg_replace($suchmuster, $ersetzungen, $zeichenkette);
?>
Gibt es sowas wie ein Pendant für preg_replace in Python?
BlackJack

Vorgefertigt nicht, müsstest Du selber implementieren. Für diesen Fall reicht `str.translate()` vielleicht schon aus. Eventuell mit einem "Umweg" über Unicode falls die Anführungszeichen nicht in einem Byte kodiert sind. Ansonsten kann man hier auch dreimal hintereinander die normale `str.replace()`-Methode aufrufen.
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

Ja, ne Schleife mit .replace() hatte ich mir auch schon gebastelt. Wollte nur wissen, ob das mit Bordmitteln besser geht. Danke
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Ist jetzt die Frage was du mit „Bordmitteln“ und „besser“ meinst.

Code: Alles auswählen

old_string = "+-"
pattern = ["+", "-"]
replacement [" ", " "]
new_string = reduce(lambda string, replace_pattern: string.replace(*replace_pattern), [old_string] + zip(pattern, replacement))
Wie schon erwähnt wäre es bei deinen Anführungsstrichen dann besser mit Unicode-Objekten zu arbeiten.
Zuletzt geändert von Darii am Montag 15. September 2008, 09:33, insgesamt 1-mal geändert.
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

lambda, zip, map + co versuche ich ja zu vermeiden, sieht aber gut aus.

Unicode - der String der bearbeitet wird ist UTF-8 - bedeutet in diesem Fall einfach ein "u" vor alles in "pattern"? Also

Code: Alles auswählen

old_string = "+-"
pattern = [u"+", u"-"]
replacement [u" ", u" "]
new_string = reduce(lambda string, replace_pattern: string.replace(*replace_pattern), [old_string] + zip(pattern, replacement))
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Vor allem, also auch vor old_string. Wenn du den allerdings irgendwo einliest musst du ihn per old_string = old_string.decode("utf-8") in einen Unicode-String umwandeln. Und oben in der Python-Datei musst du dann natürlich noch die Zeichenkodierung angeben.

PS: Wenn deine Datei und der String gleich kodiert sind wäre es auch möglich ohne Unicode-Objekte zu arbeiten, aber wehe daran ändert sich irgendwann mal was...
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

Code: Alles auswählen

old_string = "+-"
pattern = [u"+", u"-"]
replacement = [u" ", u" "]
new_string = reduce(lambda string, replace_pattern: string.replace(*replace_pattern), [old_string] + zip(pattern, replacement))
Ich hab mir das ja mal angeschaut, aber ich versteh es halt nicht.

Was ich verstehe ist:

Code: Alles auswählen

reduce((lambda x, y: x + y), [1, 2, 3, 4])
Auch Sinn macht natürlich:

Code: Alles auswählen

zip(a, b)
Aber kann mir bei dem Beispiel oben vielleicht mal jemand erklären, was da in den einzelnen Schritten passiert?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Alternativ:

Code: Alles auswählen

from itertools import starmap
from functools import partial
from functional import methodcaller, mcompose



_escape_one = partial(methodcaller, 'replace')
def create_escaper(tokens):
    return mcompose(*starmap(_escape_one, tokens))

escape = create_escaper([
    (u'%', u'?'),
    (u'-', u'+'),
    (u'1', u'2'),
])
assert escape("foo%-bar12") == "foo?+bar22"
Auch wenn ich eigentlich ein großer reduce-Fan bin ;)
BlackJack

@__marcus__: Vielleicht wird's klarer wenn man keine "gemsichte" Liste mit Anfangswert und Ersetzungspaaren erzeugt, sondern den Anfangswert als drittes Argument an `reduce()` übergibt:

Code: Alles auswählen

def main():
    old_string = '+-'
    pattern = [u'+', u'-']
    replacement = [u' ', u' ']
    
    def replace(string, (old, new)):
        return string.replace(old, new)
    
    new_string = reduce(replace,
                        zip(pattern, replacement),
                        old_string)
    print repr(new_string)
Falls das immer noch nicht hilft, versuch doch mal `reduce()` selber zu implementieren.

@audax: `functional`!? :-)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Code: Alles auswählen

import re

zeichenkette = "Wort-Haus „Katze“"

print re.sub(r"-|„|“", " ", zeichenkette)
Ausgabe:
Wort Haus Katze
oder ist vielleicht sowas gesucht:

Code: Alles auswählen

import string

def filter(txt, separator):
    parts = [""]
    for char in txt:
        if not char in string.ascii_letters:
            if parts[-1] != "":
                parts.append("")
        else:
            parts[-1] += char

    txt = separator.join(parts)
    txt = txt.strip(separator)
    return txt

print filter("Wort-Haus „Katze“", separator=" ")
print filter("Wort-Haus „Katze“", separator="-")
Ausgabe:
Wort Haus Katze
Wort-Haus-Katze

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

BlackJack hat geschrieben: @audax: `functional`!? :-)
http://audaxxx.de/functional-0.3.1.tar.gz

Das Modul hab ich mittlerweile quasi immer importiert :)
Hat so das typische, was noch fehlt:
compose, mcompose (multicompose), flip
Und noch and_, das nur prüft ob alle f(*args, **kwargs) wahrt sind für ein Iterable von Funktionen f.

Compose ist in pyrex erstellt weil die Funktionsaufrufe sonst zu teuer sind, Es läuft aber auch ohne das Pyrex-Modul, dann eben ne Ecke langsamer.

@jens:
string.asci_letters? Oo
Antworten