hilfdirselbst.ch
Facebook Twitter gamper-media
Miro Dietiker
Beiträge: 699
14. Apr 2002, 00:46
Beitrag #1 von 14
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Hallo Zusammen!

Ich habe gerade bei der Programmierung von regulären Ausdrücken massive Probleme bekommen, da diese grundsätzlich zwar extrem leistungsstark sind, aber in sehr flexiblen Situationen enorm lange zur Auswertung brauchen.

Hat jemand erfahrung in der optimierung solcher Problemdinger?

THX: Miro Dietiker Top
 
X
hmaus  M 
Beiträge: 692
14. Apr 2002, 17:23
Beitrag #2 von 14
Beitrag ID: #2671
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Mal ehrlich gesprochen Miro,

ich kenne keinen Menschen, der reguläre Ausdrücke wirklich versteht. Versuche doch einmal Dein problem zu schildern, dann können wir uns damit mal beschäftigen

Gruß,

Helge
als Antwort auf: [#2634] Top
 
Miro Dietiker
Beiträge: 699
14. Apr 2002, 21:54
Beitrag #3 von 14
Beitrag ID: #2691
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Hi Helge, ist noch interessant, da GoLive auch in Files/Auf entwickelten Seiten Reguläre ausdrücke unterstützt - kann dir sagen, dass die absolut leistungsstark sind!

Im Umgang mit Files (simplen Textdateien) ist das unumgänglich und ausserdem wird beim thema XML und beim Parsen von anderen strukturierten Daten ausschliesslich über reguläre Ausdrücke Daten rausgelesen und interpretiert.

(Wer's nicht weiss: Es geht darum in einem Datengewirr(File) Daten zu finden, indem man suchmuster festlegt. In der GoLive Suche kann man so bsp. nicht nur nach einem simplen wortlaut/text suchen, sondern ein komplexes suchmuster spezifizieren. (Optimal für grössere Datenhaufen, wenn man was bestimmtes sucht)

Wirklich interessiert? Ich denke kaum ,dass mein langer regulärer ausdruck ein verstehbares Einstiegsbeispiel wäre.

Greets: Miro

[ Diese Nachricht wurde geändert von: Miro Dietiker am 2002-04-14 22:03 ]
als Antwort auf: [#2634] Top
 
SabineP  M 
Beiträge: 7586
14. Apr 2002, 22:28
Beitrag #4 von 14
Beitrag ID: #2694
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


An welcher Stelle (Programmiersprache/Programm/Betriebssystem) setzt Du den regulären Ausdruck ein?
Wie sieht denn der reguläre Ausdruck aus?
Beides beeinflußt entscheidend die Geschwindigkeit der Ausführung (Programmlaufzeit).

[ Diese Nachricht wurde geändert von: SabineP am 2002-04-14 22:59 ]
als Antwort auf: [#2634] Top
 
Petra Rudolph p
Beiträge: 1554
15. Apr 2002, 10:09
Beitrag #5 von 14
Beitrag ID: #2700
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Zu regulären Ausdrücken hab ich diese Tut gefunden, mich aber noch nicht damit auseinander gesetzt.

http://www.php-resource.de/tutorials.php?show=20020314_Reg_p1.php
als Antwort auf: [#2634] Top
 
Anonym
Beiträge: 22827
16. Apr 2002, 18:33
Beitrag #6 von 14
Beitrag ID: #2792
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Zitat:
Wirklich interessiert? Ich denke kaum ,dass mein langer regulärer ausdruck ein verstehbares Einstiegsbeispiel wäre.
Wie sieht der Ausdruck denn aus.
Poste ihn mal und beschreibe was er machen soll.
Dann sieht man erst mal ob das optimierbar ist.
als Antwort auf: [#2634] Top
 
Miro Dietiker
Beiträge: 699
16. Apr 2002, 20:51
Beitrag #7 von 14
Beitrag ID: #2801
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Hallo zusammen!

Hier also das begehrte Ding...
Zu beachten: Nachdem ich zuerst das ereg() verwendet habe (nicht ganz kompatible RegEx!) ging das auch, ist aber bei kleinen Files schon ans Timeout von 30sec gestossen. Mit der Funktion preg_match() (RegEx-Syntax wie Perl & wie unten) geht das nun innert wenigen microsekunden (auch bei grösseren Files (HTML@10kB))

Das Herzstück:
******************
// Scan for Start/Next
while(preg_match("/^(.*)(\<\!-- *TextEdit\:(.{1,2})\:(\d{0,2})\:(.{1,16})--\>)(.*)/s",$ft, $s_regs))
{
#1: PreRest #2: Whole Start Field #3: Fieldtype #4: Titel #5: AfterRest
$arr[$arrcount]['title'] = $s_regs[5];
$arr[$arrcount]['size'] = $s_regs[4];
$arr[$arrcount]['type'] = $s_regs[3];
$arr[$arrcount]['start'] = $s_regs[2];
// Scan for end
preg_match("/^(.*)(\<\!-- *TextEdit\:END\:".$s_regs[5]." *--\>)(.*)/s",$s_regs[6],$e_regs);
#1: Field Content #2: Whole End Field #3: Rest
$arr[$arrcount]['text'] = $e_regs[1];
$arr[$arrcount]['end'] = $e_regs[2];
// Restructurate / Next element
$ft = $s_regs[1].$e_regs[3];
$arrcount++;
}
******************
Es sucht Elemente (Kommentartags in Files) mit folgender Struktur:
******************
<!--TextEdit:mz:5:Beschreibung1-->blablabla<!--TextEdit:END:Beschreibung1-->
<!--TextEdit:mz:5:Beschreibung2-->blablabla<!--TextEdit:END:Beschreibung2-->
******************

Zunächst war ich verwundert, dass meine schleife das Letzte zuerst fand! Deshalb schneide ich das gefundene raus und klebe das übrige zusammen und suche nochmals... So Findet es die Felder von hinten her (geordnet!)
Die Reihenfolge von Vorne wär mir lieber und ich weiss auch nicht weshalb das nicht geht.
Die Definition der Assoziativität wird mit grösster Wahrscheinlichkeit weiterhelfen, ich versteh aber nicht ganz wie das funzt (Tags wie ?> und ?< )
(ausserdem änderte es nichts, wenn ichs verwendete)

Am Schluss habe ich ein Mehrdimensionales Array, wobei die erste Dimension (Zeilennummer) die Nummer des gefundenen Objektes repräsentiert (von hinten) und die zweiten Indizes Assoziativ sind.

Was meint Ihr dazu?

Besten Dank für eure Mithilfe.

Miro Dietiker

[ Diese Nachricht wurde geändert von: Miro Dietiker am 2002-04-16 20:58 ]
als Antwort auf: [#2634] Top
 
Anonym
Beiträge: 22827
16. Apr 2002, 21:14
Beitrag #8 von 14
Beitrag ID: #2802
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


!-- BBCode Quote Start -->
Zitat:
Miro Dietiker schrieb am 2002-04-16 20:51 :
******************
Es sucht Elemente (Kommentartags in Files) mit folgender Struktur:
******************
blablabla
blablabla
******************
Frage:
Ist in dem blabla ein Zeilenumbruch zu
erwarten, wenn nein, dann läßt sich noch einiges vereinfachen?
Zitat:
Zunächst war ich verwundert, dass meine schleife das Letzte zuerst fand!
Das ist nicht verwunderlich da, regexp's im allgemeinen
gierig sind, d.h. es wird das gematcht, wass am meisten bringt.
als Antwort auf: [#2634] Top
 
Miro Dietiker
Beiträge: 699
17. Apr 2002, 01:52
Beitrag #9 von 14
Beitrag ID: #2811
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Ja leider sind Zeilenumbrüche zu erwarten..
(würde mich aber wundernehmen, was ich am besten ändern könnte, wenn da keine vorkämen...)

Des weiteren, verstehe ich trotz der Gierigkeit *g* nicht, weshalb das letzte zuerst gefunden wird (Ich brauche alle Vorkommnisse) und frage mich deshalb, ob man dies nicht im Ausbruch definieren kann, dass der vom Beginn her suchen soll... In meinem Fall wäre der Reihe nach effizienter...

THX: Miro

[ Diese Nachricht wurde geändert von: Miro Dietiker am 2002-04-17 01:54 ]
als Antwort auf: [#2634] Top
 
Anonym
Beiträge: 22827
17. Apr 2002, 17:02
Beitrag #10 von 14
Beitrag ID: #2845
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Es liegt schon daran, daß die regexp's greedy sind.
In deinem Audruck der so beginnt, ^(.*), werden erstmal
alle Zeichen in die 1. Gruppe aufgenommen bis dein gesamter
String durch ist und ein match gefunden wurde.
das ist dann logischerweise der letzte.
dann wird in deinen String das übernommen, was noch übrig ist($ft = $s_regs[1].$e_regs[3];). Also alles vor dem match
und der Kram danach. Dann geht der ganze Zirkus von
vorne los, bis im String kein match mehr zu finden ist.
als Antwort auf: [#2634] Top
 
Anonym
Beiträge: 22827
17. Apr 2002, 17:10
Beitrag #11 von 14
Beitrag ID: #2846
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Hier noch der Rest:
probier mal den ersten Ausdruck ungreedy.
so hier:
while(preg_match("/^(.*?)(\<\!
-----------------------^

dann sollte es gehen, möglicherweise sogar schneller.
als Antwort auf: [#2634] Top
 
Miro Dietiker
Beiträge: 699
17. Apr 2002, 19:54
Beitrag #12 von 14
Beitrag ID: #2848
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Hi Anonyme Hilfe

Ja jetzt verstehe ich endlich, wie das mit dem "greedy" und "ungreedy" und den zugehörenden modifyers funktioniert. Die Funktion habe ich jetzt umgeschrieben, das Zusammensetzen ist jetzt nicht mehr nötig weil man einfach im danach folgenden weitersuchen kann, das erste wird zuerst gefunden, und um ein vielfaches ist es auch noch schneller.

Einzig was ich noch nicht begriffen habe aus der Dokumentation von PHP (Thema "Pattern Syntax") ist die Beschreibung zu dem Operator > und <
Kannst Du dazu vielleicht auch noch eine kurze Erklärung verlauten lassen?

Besten Dank für Deine Hilfe : Miro

PS: Meld dich doch an, dann wissen wir, mit wem wir's zu tun haben - würd uns alle sehr wunder nehmen...
als Antwort auf: [#2634] Top
 
oesi50  A  S
Beiträge: 2315
17. Apr 2002, 22:39
Beitrag #13 von 14
Beitrag ID: #2853
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


Jetzt nicht mehr anonym.

versuchs mal damit:
while(preg_match("/(<!-- *TextEdit:(.{1,2}):(\d{0,2}):(.{1,16}) *-->)(.*?)(<!-- *TextEdit:END:.*? *-->)(.*)/s",$ft,$s_regs))
{
$arr[$arrcount]['start'] = $s_regs[1];
$arr[$arrcount]['type'] = $s_regs[2];
$arr[$arrcount]['size'] = $s_regs[3];
$arr[$arrcount]['title'] = $s_regs[4];
$arr[$arrcount]['text'] = $s_regs[5];
$arr[$arrcount]['end'] = $s_regs[6];
$ft = $s_regs[7];
$arrcount++;
}
Schneller wird das noch, wenn man auf den Hash
verzichtet, da ja 1 bis 6 immer den selben Schlüssel hat.

ich glaube das reicht.
Hier gibt es nur noch das eine Problem,

wenn die Start und Ende Tags so geschachtelt sind:

s1 baz baz s2 boo boo e1 e2

dann hilft letztendlich nur noch ein Parser.

Zu der Frage nach < und > kann ich nur
auf das PHP Manual verweisen.
Ganz kurz:
Bei ereg (POSIX regexp) ist das die Wortbegrenzung.
Bei preg (Perl regexp) wird das im Zusammenhang
mit dem 'vorausschauenden' matching verwendet.

Beim 'normalen' matching werden die getesteten Zeichen
'verbraucht'. Im Gegensatz zum 'vorausschauenden'
matching, wo die Zeichen schon mal 'zur Probe' getestet werden können.

Zitat:

(?<=pattern)

A zero-width positive look-behind assertion.
For example, /(?<=t)w+/ matches a word that follows a tab, without including the tab in $&. Works only for fixed-width look-behind.

(?<!pattern)

A zero-width negative look-behind assertion.
For example /(?<!bar)foo/ matches any occurrence
of ``foo'' that does not follow ``bar''. Works only for fixed-width look-behind.




[ Diese Nachricht wurde geändert von: oesi50 am 2002-04-17 22:57 ]
als Antwort auf: [#2634] Top
 
Miro Dietiker
Beiträge: 699
18. Apr 2002, 20:27
Beitrag #14 von 14
Beitrag ID: #2874
Bewertung:
(3241 mal gelesen)
URL zum Beitrag
Beitrag als Lesezeichen

Probleme mit Regulären Ausdrücken


So, lieber oesi50

Ich habe jetzt dieses Gebilde auf eine Zeile reduziert
(ähnlich wie deine erklärung) nur habe ich die Syntax es zu findenden Ausdruckes noch etwas anpassen müssen...

Jedenfalls ist dieses Problem mit Sicherheit vom Tisch.

Die versetzte verschachtelung ist mit Sicherheit kein Problem, weil sie in diesem Fall absolut unzulässig ist.

Besten Dank - Miro
als Antwort auf: [#2634] Top
 
X