Seite 1 von 1

reguläre ausdrücke mit python

Verfasst: Donnerstag 13. März 2008, 07:33
von mondschein
hallo,
ich habe ein kelines problem mit einer meiner extension (ich benutze mediawiki 1.10), welche in python geschrieben ist. das ganze problem findet sich hier (http://www.python-forum.de/topic-13876.html), da konnte mir aber leider niemand helfen :( . Meine "neue"Frage nun: kann mir jemand helfen zu entschlüsseln was genau diese funktion macht? (ich bin nciht so doll bewandert in python)...

Code: Alles auswählen

def doWiki(text):
	#display-style math should be centered
	text = re.sub(r'(?s)\n:+ *<math>(.*?)</math>\s*?([\.,;]?)\n', doMath, text)	
	
	text = re.sub(r'()\{([^|])', r'\\{\2', text)
	text = re.sub(r'()([^|])\}', r'\2\\}', text)
	text = doPreFormatted(text)

	# take care of lists, tables and images
	text = doIndent(text)
	text = doTables(text)
	text = doImages(text)	
	# first convert all HTML entities to Unicode

	text = re.sub('&#([0-9]+?);', uni_dec2utf8, text)
	text = re.sub('&#[xX]([0-9A-Fa-f]+?);', uni_hex2utf8, text)
	text = re.sub('&([a-zA-Z0-9]+?);', entity2utf8, text)

	text = re.sub(r'\$', r'\$', text)
	# multi-pass regexp parser

	for trans_tuple in translate:

		print "replacing " + trans_tuple[0]
		text = re.sub(trans_tuple[0], trans_tuple[1], text)	
	print "done"	
	# convert Unicode character to latex markup if possible
	text = unicode2latex.convert2(text)
	return text


also ich rufe dies methode mit einem text (den ganzen text) auf und dann gucke ich ob irgendwo math steht und rufe dann diese funktion auf:

Code: Alles auswählen

def doMath(mathtext):
	mtext = mathtext.group(1).replace("&", "tableand")
	mtext = re.sub(r'\n[ \t]*', r'\n', mtext) #remove whitespace at beginning of line
	return "\n\\[" + mtext + mathtext.group(2) + "\\]\n"
nur was mache ich hier genau!? ich "schneide" das <math> weg!? und nehm alle leerzeichen raus? und was gebe ich zum schluß zurück!? (bsp. <math>x=y+z</math>)

text = re.sub(r'()\{([^|])', r'\\{\2', text) --> was bedeutet hier die \2!?

text = re.sub(r'\$', r'\$', text) --> :?:

text = re.sub(trans_tuple[0], trans_tuple[1], text) --> und hier gucke ich in meinen translate array tupel [0] ist was ich suche im text und tupel[1] ist womit ich es ersetzte oder?!

danke für hilfe :oops:

Verfasst: Donnerstag 13. März 2008, 11:11
von BlackJack
`doWiki()` wendet verschiedene Suchen/Ersetzen-Vorgänge, auf den übergebenen `text` an.

Als erstes wird etwas behandelt, was sich in Mediawiki wohl "display style math" nennt. Der reguläre Ausdruck mal auseinander genommen:

'(?s)' - Eine Steueranweisung die sagt, dass der Punkt ('.') auch auf Zeilenumbrüche zutrifft.

'\n' - Ein Zeilenumbruch,

':+' - gefolgt von mindestens einem Doppelpunkt,

' *' - und optionalen Leerzeichen,

'<math>' - dem Anfangstag,

'(.*?)' - beliebigen Zeichen ("non-greedy", Gruppe 1),

'</math>' - dem Endtag,

'\s*?' - optionale Leerzeichen ("non-greedy")

'([\.,;]?)' - optional eines der Zeichen Punkt, Komma oder Semikolon (Gruppe 2),

'\n' - und ein Zeilenumbruch.

Das trifft also zum Beispiel auf diese Zeichenkette zu: '\n:<math>foo</math>.\n'

Für die Ersetzung wird die `doMath`-Funktion mit einem "match"-Objekt aufgerufen und muss den Text zurückgeben, durch den der Treffer ersetzt werden soll.

Die Funktion schnappt sich Gruppe 1 und ersetzt dort '&'-Zeichen durch das Wort 'tableand'. Ersetzt führende Leerzeichen durch einen Zeilenumbruch und formatiert das Ergebnis + der zweiten Gruppe zwischen eckige Klammern mit einem Gegenschrägstrich davor. Beispiel:

Code: Alles auswählen

In [41]: def doMath(mathtext):
   ....:     mtext = mathtext.group(1).replace("&", "tableand")
   ....:     mtext = re.sub(r'\n[ \t]*', r'\n', mtext)
   ....:     return "\n\\[" + mtext + mathtext.group(2) + "\\]\n"
   ....:

In [42]: import re

In [43]: text = '\n:<math>foo & bar</math>.\n'

In [44]: re.sub(r'(?s)\n:+ *<math>(.*?)</math>\s*?([\.,;]?)\n', doMath, text)
Out[44]: '\n\\[foo tableand bar.\\]\n'
----

Ein Gegenschrägstrich gefolgt von einer Ziffer in der Ersetzungszeichenfolge bedeutet, dass dort die Gruppe mit der angegebenen Nummer eingesetzt wird.

----

``re.sub(r'\$', r'\$', text)`` ersetzt Dollarzeichen durch die Zeichenfolge Gegenschrägstrich + Dollarzeichen.

Code: Alles auswählen

In [45]: re.sub(r'\$', r'\$', 'Eine handvoll $')
Out[45]: 'Eine handvoll \\$'
----

Wenn Dir Gruppen und "non-greedy" nichts sagen, such mal ein Tutorial über reguläre Ausdrücke.