Seite 1 von 1
Wo ist hier der Fehler? - & frage zu '' match '' Objekte
Verfasst: Donnerstag 14. Dezember 2006, 15:29
von EnTeQuAk
hallo alle zusammen!
Ich bin gerade so am rumspielen und bastel halt so n bissl rum.
Nun habe ich mal etwas gebastelt, um bestimmte Strings in einem Text zu ersetzen.
Der Teil, um den es geht ist dieser:
Code: Alles auswählen
def replace_headers(data, HeaderList):
for header, level in HeaderList:
header.replace(header, '<h%d>%s</h%d>' %(level, header[level:len(header)-(level+1)]))
Wenn ich das ganze nun ausführe erhalte ich eine Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "testing.py", line 47, in ?
HEADLINE_FUNCTION(template, HEADLINE)
File "testing.py", line 41, in HEADLINE_FUNCTION
replaced = replace_headers(data, HeaderList)
File "testing.py", line 38, in replace_headers
header.replace(header, '<h%d>%s</h%d>' %(level, header[level:len(header)-(level+1)]))
TypeError: not enough arguments for format string
Verstehen tue ich die schon. Aber so richtig verstehen, wo da ein Argument fehlt tue ich nicht.
Könnt ihr mit helfen?
MfG EnTeQuAk
Verfasst: Donnerstag 14. Dezember 2006, 15:33
von CM
Hoi,
ganz einfach:
Du willst drei Argumente inserieren: %d, %s und %d übergibst aber nur zwei, nämlich "level" und "header[level:len(header)-(level+1)]". Wie Du an das dritte Argument kommst, mußt Du nun selber herausfinden, bzw. ob Du das überhaupt so willst.
HTH
Christian
Verfasst: Donnerstag 14. Dezember 2006, 15:35
von EnTeQuAk
Ach... ich bin ein trottel

*peinlich*
Danke! Kommt davon, wenn man da so viel noch zwischendrinne stehen hat!
MfG EnTeQuAk
Verfasst: Donnerstag 14. Dezember 2006, 16:56
von BlackJack
Was soll das der Slice denn eigentlich liefern? Der Sinn erschliesst sich mir nicht ganz:
Code: Alles auswählen
In [17]: for level in xrange(len(header)):
....: header[level:len(header)-(level+1)]
....:
Out[17]: ['a', 'b', 'c']
Out[17]: ['b']
Out[17]: []
Out[17]: []
Verfasst: Donnerstag 14. Dezember 2006, 17:00
von EnTeQuAk
So schauts aus, wenns "fertig" ist... es mag verbesserungswürdig sein funktioniert aber:
Code: Alles auswählen
# -*- coding: utf-8 -*-
import re
template = '''ich bin eine =tolle1 Über===schrift= dasda dada
ich bin auch eine == tolle2 Über===schrift == dasd a
na und ich bin auch eine === tolle3 Über===schrift === dasda
und ich bin ==== keine Überschrift mehr da vier mal = ====
und noch ne === dreier ueberschrift ===
======== test ? ===========
'''
# defines Regex-Syntax
HEADLINE = re.compile(r'(={1,3}\s*.*={1,3})')
def HEADLINE_FUNCTION(data, regex):
#print regex.findall(data) # testeweise
def getHeaderList(data, regex):
HeaderList = []
for string in regex.findall(data):
if string.startswith(r'====') and string.endswith(r'===='):
# hiermit fische ich alles heraus, was laenger als drei mal = ist
continue
elif string.startswith(r'===') and string.endswith(r'==='):
HeaderList.append((string, 3))
elif string.startswith(r'==') and string.endswith(r'=='):
HeaderList.append((string, 2))
elif string.startswith(r'=') and string.endswith(r'='):
HeaderList.append((string, 1))
else:
# don't say never :D
continue
return HeaderList
def replace_headers(data, HeaderList):
count = 0
for header, level in HeaderList:
tmp_data = data.replace(header, '<h%d>%s</h%d>' %(level, header[level:len(header)-(level)], level))
print tmp_data
data = tmp_data
count +=1
return data
HeaderList = getHeaderList(data, regex)
print 'HeaderList: \n%s\n' % HeaderList
print 'Ausgangstemplate: \n%s' % template
data = replace_headers(data, HeaderList)
print 'Fertige Header: \n\n%s' % data
if __name__ == '__main__':
HEADLINE_FUNCTION(template, HEADLINE)
edit: kleinen Fehler weggemacht... er hat zu viel abgeschnitten
Ausgabe wäre dann folgende:
Code: Alles auswählen
ente@Proggi-PC:~/Desktop/daucms$ python testing.py
HeaderList:
[('=tolle1 \xc3\x9cber===schrift=', 1), ('== tolle2 \xc3\x9cber===schrift ==', 2), ('=== tolle3 \xc3\x9cber===schrift ===', 3), ('=== dreier ueberschrift ===', 3)]
Ausgangstemplate:
ich bin eine =tolle1 Über===schrift= dasda dada
ich bin auch eine == tolle2 Über===schrift == dasd a
na und ich bin auch eine === tolle3 Über===schrift === dasda
und ich bin ==== keine Überschrift mehr da vier mal = ====
und noch ne === dreier ueberschrift ===
======== test ? ===========
Fertige Header:
ich bin eine <h1>tolle1 Über===schrift</h1> dasda dada
ich bin auch eine <h2> tolle2 Über===schrift </h2> dasd a
na und ich bin auch eine <h3> tolle3 Über===schrift </h3> dasda
und ich bin ==== keine Überschrift mehr da vier mal = ====
und noch ne <h3> dreier ueberschrift </h3>
======== test ? ===========
Ich denke, das das reicht um zu erklären, wofür ich das benötige
Ist halt erstmal nur rumgespiele...
MfG EnTeQuAk
Verfasst: Donnerstag 14. Dezember 2006, 18:02
von BlackJack
Du kannst bei Slices auch negative Werte angeben. Folgendes ist äquivalent:
Deinen Quelltext kann man etwas kürzen wenn man das Erkennen von gleichlangen '='-Markierungen vor und hinter der Überschrift schon im regulären Ausdruck erledigt:
Code: Alles auswählen
HEADLINE = re.compile(r'(=+)(\s*.*)(\1)')
def HEADLINE_FUNCTION(data, regex):
def getHeaderList(data, regex):
HeaderList = []
for match in regex.findall(data):
level = len(match[0])
if level <= 3:
HeaderList.append((match[1], level))
return HeaderList
def replace_headers(data, HeaderList):
for header, level in HeaderList:
markup = '=' * level
data = data.replace(markup + header + markup,
'<h%d>%s</h%d>' % (level, header, level))
return data
Noch etwas übersichtlicher wird es wenn Du gleich die Ersetzungsmethode von regulären Ausdrücken benutzt. Da kannst Du anstelle eines Ersetzungsmusters auch eine Funktion angeben, die das `match`-Objekt bekommt und die Zeichenkette liefert, die stattdessen eingesetzt werden soll.
Verfasst: Sonntag 17. Dezember 2006, 10:54
von EnTeQuAk
Nun habe ich letzteres auch endlich verstanden
Jedoch habe ich nun evtl. ein rein Logisches Problem.
Ich habe nun ein Match Objekt. Wie kann ich nun daraus die Zeichenkette liefern. Welche Funktion aktzeptiert Match Objete - wie kann ich den Match ausliefern bzw. was kann man mit denen so alles machen?
Ich finde nicht mal in meinem Buch gute Beispiele. Könntet ihr mir eventuell ein paar geben?
Herzlichen Dank!
MFG EnTeQuAk
Verfasst: Sonntag 17. Dezember 2006, 11:49
von birkenfeld
Siehe
http://docs.python.org/lib/match-objects.html
Den gesamten "gematchten" Text bekommst du mit match.group(), einzelne Subgruppen mit match.group(x).
Verfasst: Sonntag 17. Dezember 2006, 11:50
von BlackJack
EnTeQuAk hat geschrieben:Ich habe nun ein Match Objekt. Wie kann ich nun daraus die Zeichenkette liefern. Welche Funktion aktzeptiert Match Objete - wie kann ich den Match ausliefern bzw. was kann man mit denen so alles machen?
Die Funktion musst Du selbst schreiben. Für jeden Treffer bekommt die das `match`-Objekt und kann damit alles machen was so in der Doku steht. Also zum Beispiel auf die einzelnen Gruppen mit der `group()`-Methode zugreifen. Die Funktion muss eine Zeichenkette zurückliefern die dann anstelle der "gematchten" Zeichenkette eingesetzt wird.
Ich finde nicht mal in meinem Buch gute Beispiele. Könntet ihr mir eventuell ein paar geben?
Gleich ein paar?
Man kann das immer anwenden, wenn man beim suchen und ersetzen mittels regulärer Ausdrücke nicht einfach nur Text durch anderen, mehr oder weniger statischen Text, ersetzen will, sondern den gefundenen Text durch etwas berechnetes ersetzen möchte. Simples Beispiel: man möchte alle Hexadezimalzahlen in einem Text durch eine entsprechende Dezimaldarstellung ersetzen. Hexadezimalzahlen werden im Beispiel durch ein führendes '0x' oder ein '$' gekennzeichnet:
Code: Alles auswählen
import re
def main():
test = 'spam 0x123def, $EA31 eggs'
hex_re = re.compile(r'(0x|\$)(?P<digits>[0-9a-fA-F]+)')
def convert(match):
return str(int(match.group('digits'), 16))
print hex_re.sub(convert, test)
Dein Überschriftenersetzen kann man dann so lösen:
Code: Alles auswählen
HEADLINE = re.compile(r'(=+)(\s*.*)(\1)')
def HEADLINE_FUNCTION(data, regex):
def replace_header(match):
level = len(match.group(1))
if level > 3:
return match.group(0)
else:
return '<h%d>%s</h%d>' % (level, match.group(2), level)
print 'Ausgangstemplate: \n%s' % template
data = HEADLINE.sub(replace_header, template)
print 'Fertige Header: \n\n%s' % data
Verfasst: Sonntag 17. Dezember 2006, 12:58
von EnTeQuAk
Ahhh

an die '' grou() '' Funktion hab ich gar net mehr gedacht
Herzlichen Dank, für das Beispiel!
Nun funktioniert auch endlich alles
MfG EnTeQuAk