{"id":10,"date":"2008-05-13T18:33:03","date_gmt":"2008-05-13T16:33:03","guid":{"rendered":"http:\/\/mediamill.mediamill.info\/blog\/2008\/01\/06\/problem-mit-regulaeren-ausruecken\/"},"modified":"2008-04-07T00:14:18","modified_gmt":"2008-04-06T22:14:18","slug":"problem-mit-regulaeren-ausruecken","status":"publish","type":"post","link":"https:\/\/www.mediamill.de\/blog\/2008\/05\/13\/problem-mit-regulaeren-ausruecken\/","title":{"rendered":"Regul\u00e4re Ausdr\u00fccke &#8211; regex, singleline, non-greedy"},"content":{"rendered":"<p>Ich habe mich bisher nur so viel wie n\u00f6tig mit regul\u00e4ren Ausdr\u00fccken besch\u00e4ftigt. Der komplexe Syntax und das kryptische Aussehen der regul\u00e4ren Ausdr\u00fccke haben mich bisher davon abgeschreckt, regul\u00e4re Ausdr\u00fccke zu benutzen. K\u00fcrzlich hatte ich aber das Problem, in vb.net Text zwischen einer Startmarkierung und einer Endmarkierung zu suchen. Nat\u00fcrlich kann man das auch mit den .net Stringfunktionen erreichen, aber ich wollte es dieses Mal mit regul\u00e4ren Ausdr\u00fccken versuchen.<\/p>\n<p>Nach einigen Anfangsproblemen bin ich nun richtig begeistert von der M\u00e4chtigkeit der regul\u00e4ren Ausdr\u00fccke.<\/p>\n<p>Mein erstes Problem war, dass sich mein zu analysierender Text \u00fcber mehrere Zeilen zog, also waren Zeilenumbr\u00fcche vorhanden. Ebenso zogen sich die zu extrahierenden Textstellen \u00fcber mehrere Zeilen. Meine regul\u00e4ren Ausdr\u00fccke lieferten nicht das erwartete Ergebnis. Besser gesagt: Sie lieferten gar kein Ergebnis.<\/p>\n<p>Nach etwas Internetrecherche erfuhr ich, dass bei der Erstellung eines regex Objektes Optionen angegeben werden k\u00f6nnen. In vb.net findet sich das Ganze unter: <strong>System.Text.RegularExpressions.RegexOptions<\/strong><\/p>\n<p>Ohne weiter nachzulesen, w\u00e4hlte ich die Option <strong>Multiline<\/strong>, da ich ja Text zeilen\u00fcbergreifend analysieren wollte. Diese Option lieferte aber zu meiner \u00dcberraschung ebenfalls kein Ergebnis.<\/p>\n<p>Also machte ich mich daran, die Optionen n\u00e4her anzuschauen. Dabei fand ich eine weitere Option: <strong>Singleline<\/strong>. Und genau diese muss man angeben, um das gew\u00fcnschte Ergebnis zu erreichen. Ich finde das Ganze zwar etwas verwirrend: <strong>Singleline<\/strong> f\u00fcr zeilen\u00fcbergreifendes Analysieren &#8211; aber Hauptsache, es funktioniert.<\/p>\n<p>Wenn man also Text in vb.net mit regul\u00e4ren Ausdr\u00fccken \u00fcber mehrere Zeilen hinweg analysieren m\u00f6chte, muss man folgende Option einstellen:<\/p>\n<p><strong>System.Text.RegularExpressions.RegexOptions.Singleline<\/strong><\/p>\n<p>Beispiel:<\/p>\n<p>Text, der analysiert werden soll:<\/p>\n<p class=\"codeblock\">start  text1<br \/>\ntext2<br \/>\ntext3 ende<\/p>\n<p>Regul\u00e4rer Ausdruck: <strong>start(.*)ende<\/strong><\/p>\n<p>Dieser Ausdruck soll einen String zwischen start und ende extrahieren.<\/p>\n<p>Ergebnis ohne die Option <strong>Singleline<\/strong>:<\/p>\n<p>&#8211; Es wird nichts gefunden<\/p>\n<p>Ergebnis mit der Option <strong>Singleline<\/strong>:<\/p>\n<p class=\"codeblock\">text1<br \/>\ntext2<br \/>\ntext3<\/p>\n<p>Danach tauchte aber ein weiteres Problem auf. Bei sich mehrfach wiederholenden Mustern im Text, wurde immer die gr\u00f6\u00dftm\u00f6gliche Ergebnismenge zur\u00fcckgeliefert. Ich brauchte aber jede einzelne Ergebnismenge. Das Ganze wird an einem Beispiel deutlicher:<\/p>\n<p>Text, der analysiert werden soll:<\/p>\n<p class=\"codeblock\">start  text1<br \/>\ntext2<br \/>\ntext3 ende<br \/>\nstart  text4<br \/>\ntext5<br \/>\ntext6 ende<\/p>\n<p>Der Regul\u00e4rer Ausdruck: <strong>start(.*)ende <\/strong>liefert folgendes Ergebnis:<\/p>\n<p class=\"codeblock\">text1<br \/>\ntext2<br \/>\ntext3 ende<br \/>\nstart  text4<br \/>\ntext5<br \/>\ntext6<\/p>\n<p>Gew\u00fcnscht waren aber 2 Ergebnismengen:<\/p>\n<p>Ergebnis 1:<\/p>\n<p class=\"codeblock\">text1<br \/>\ntext2<br \/>\ntext3<\/p>\n<p>Ergebnis 2:<\/p>\n<p class=\"codeblock\">text4<br \/>\ntext5<br \/>\ntext6<\/p>\n<p>Bei der L\u00f6sung dieses Problems stie\u00df ich auf die Begriffe <strong>greedy<\/strong> (gierig) und <strong>non-greedy<\/strong> (nicht gierig) im Zusammenhang mit der Definition von regul\u00e4ren Ausdr\u00fccken. <strong>Greedy<\/strong> bedeutet, es wird immer die gr\u00f6\u00dftm\u00f6gliche Ergebnismenge zur\u00fcckgeliefert und <strong>non-greedy<\/strong> bedeutet, es wird die kleinstm\u00f6gliche Ergebnismenge zur\u00fcckgeliefert.  Standartm\u00e4\u00dfig zeigen regul\u00e4re Ausdr\u00fccke ein <strong>&#8222;gieriges (greedy)&#8220;<\/strong> Verhalten. Um ein <strong>&#8222;nicht gieriges (non-greedy)&#8220;<\/strong> Verhalten zu erreichen, muss man bei der Definition von regul\u00e4ren Ausdr\u00fccken nach dem Quanifizierer noch ein ? anf\u00fcgen.<\/p>\n<p>Beispiel:<\/p>\n<p>Text, der analysiert werden soll:<\/p>\n<p class=\"codeblock\">start  text1<br \/>\ntext2<br \/>\ntext3 ende<br \/>\nstart  text4<br \/>\ntext5<br \/>\ntext6 ende<\/p>\n<p>Der regul\u00e4re Ausdruck: <strong>start(.*?)ende <\/strong>liefert das gew\u00fcnschte Ergebnis:<\/p>\n<p>Ergebnis 1:<\/p>\n<p class=\"codeblock\">text1<br \/>\ntext2<br \/>\ntext3<\/p>\n<p>Ergebnis 2:<\/p>\n<p class=\"codeblock\">text4<br \/>\ntext5<br \/>\ntext6<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich habe mich bisher nur so viel wie n\u00f6tig mit regul\u00e4ren Ausdr\u00fccken besch\u00e4ftigt. Der komplexe Syntax und das kryptische Aussehen der regul\u00e4ren Ausdr\u00fccke haben mich bisher davon abgeschreckt, regul\u00e4re Ausdr\u00fccke zu benutzen. K\u00fcrzlich hatte ich aber das Problem, in vb.net Text zwischen einer Startmarkierung und einer Endmarkierung zu suchen. Nat\u00fcrlich kann man das auch mit [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17,16,6,18],"tags":[],"class_list":["post-10","post","type-post","status-publish","format-standard","hentry","category-regex","category-regulaere-ausdruecke","category-tipps","category-vbnet"],"_links":{"self":[{"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/posts\/10","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/comments?post=10"}],"version-history":[{"count":0,"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/posts\/10\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/media?parent=10"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/categories?post=10"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mediamill.de\/blog\/wp-json\/wp\/v2\/tags?post=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}