expertenaustausch > comp.lang.* > comp.lang.php.misc

Thomas -Balu- Walter (09.11.2003, 18:32)
Hoi,

vielleicht sehe ich den Wald vor lauter preg-Spielereien heute nicht
mehr, aber gibt es eine Moeglichkeit, einen String wie 'param1; param2;'
in seine durch ";" getrennten Teile zu splitten?

preg_match('/([^;]*);/s', 'param1; param2;', $matches);
liefert mir ja leider nur den ersten part "param1"

Ich moechte uebrigends nicht explode() benutzen, weil das ganze ein Teil
eines groesseren Ausdrucks werden soll - wenn es denn moeglich ist:

preg_match('/<!--\s*(Feld)\s*:\s*([^;]*?)\s*;\s*(.*?)\s*-->/s',
'<!-- Feld : Name des Feldes; param1; param2;-->', $matches);

Das ganze soll dann an Stelle der letzten (.*?)-Klammer stehen.

Falls jemand ausserdem noch einen Tipp hat, wie ich das ';' hinter dem
'Name des Feldes' optional machen kann, waere ich ihm sehr dankbar :)
Ziel dieser Ueberlegung waere einen String wie <!-- Feld : Name des
Feldes --> zu erlauben.

Balu
Jens Peter Möller (09.11.2003, 18:38)
Hallo Thomas -Balu- Walter, Du schriebst:

> vielleicht sehe ich den Wald vor lauter preg-Spielereien heute nicht
> mehr, aber gibt es eine Moeglichkeit, einen String wie 'param1;
> param2;' in seine durch ";" getrennten Teile zu splitten?
> preg_match('/([^;]*);/s', 'param1; param2;', $matches);
> liefert mir ja leider nur den ersten part "param1"


Du suchst preg_match_all() -

Gruß, JPM
steffen horst (09.11.2003, 20:49)
Moin

> Ich moechte uebrigends nicht explode() benutzen, weil das ganze ein Teil
> eines groesseren Ausdrucks werden soll - wenn es denn moeglich ist:
> preg_match('/<!--\s*(Feld)\s*:\s*([^;]*?)\s*;\s*(.*?)\s*-->/s',
> '<!-- Feld : Name des Feldes; param1; param2;-->', $matches);


Im letzten Element von $matches stehen ja Deine Parameter. Die könntest Du
raussuchen z.b. durch

preg_split('/\s*;\s*/', $matches[2]);

(wobei der Index 2 ist, wenn Du in Deinem Pattern die Klammern um "Feld"
löscht). Oder halt mit explode() + trim().

> Das ganze soll dann an Stelle der letzten (.*?)-Klammer stehen.


Ich weiss das nicht in einen regulären Ausdruck zu packen (außer mit einer
längeren |-Konstruktion, aber das wäre unsinnig).

> Falls jemand ausserdem noch einen Tipp hat, wie ich das ';' hinter dem
> 'Name des Feldes' optional machen kann, waere ich ihm sehr dankbar :)
> Ziel dieser Ueberlegung waere einen String wie <!-- Feld : Name des
> Feldes --> zu erlauben.


Optional geht durch '?' (0x oder 1x). Du müsstest den Teil klammern und
ein '?' hintersetzen.

Steffen
Thomas -Balu- Walter (10.11.2003, 00:12)
* Jens Peter =?ISO-8859-1?Q?M=F6ller?= wrote:
> Hallo Thomas -Balu- Walter, Du schriebst:
> Du suchst preg_match_all() -


Nein, das obige war nur ein Teilproblem - wenn ich den String nur an den
";" trennen wollte, wuerde ich explode() nehmen. Meine Frage bezog sich
mehr darauf, wie man diese Trennung in den "grossen" Regex integrieren
koennte.

Ich brauche also eine match_all innerhalb eines groesseren Ausdrucks.

Balu
Thomas -Balu- Walter (10.11.2003, 00:31)
In article <oprydvw2xo822tll>, steffen horst wrote:
> Ich weiss das nicht in einen regulären Ausdruck zu packen (außer mit einer
> längeren |-Konstruktion, aber das wäre unsinnig).


Gut, genau das habe ich naemlich auch gedacht. Ich war mir nur nicht
sicher, ob es vielleicht einen speziellen Ausdruck fuer die preg gibt,
der das erlauben wuerde.

> > Falls jemand ausserdem noch einen Tipp hat, wie ich das ';' hinter dem
> > 'Name des Feldes' optional machen kann, waere ich ihm sehr dankbar :)
> > Ziel dieser Ueberlegung waere einen String wie <!-- Feld : Name des
> > Feldes --> zu erlauben.

> Optional geht durch '?' (0x oder 1x). Du müsstest den Teil klammern und
> ein '?' hintersetzen.


Ich habs die ganze Zeit ohne Klammer versucht: ';?' - das sollte keinen
Unterschied machen, oder? Trotzdem faellt mir der regex dann in den Ruecken:

preg_match('/<!--\s*(Feld)\s*:\s*([^;]*?)\s*;\s*(.*?)\s*-->/s',
'<!-- Feld : Name des Feldes; -->', $matches);
Array
(
[0] => <!-- Feld : Name des Feldes; -->
[1] => Feld
[2] => Name des Feldes
[3] =>
)

Wenn ich aus dem zweiten ';' dann ein '(;)?' mache, wirft es mir natuerlich das
ganze Ergebnis durcheinander:
Array
(
[0] => <!-- Feld : Name des Feldes; -->
[1] => Feld
[2] =>
[3] =>
[4] => Name des Feldes;
)

Der betroffene Teilstring wird so erst von der letzten Klammer '(.*?)'
gematcht. Ich glaube die greedyness springt mir hier in die Quere?
Das ist insbesondere bloed, weil das dann evtl. auch auf einen String mit
Paramtern zutrifft. Der letzte Match ist dann halt 'Name des Feldes; param1;
param2;'

Tja, niemand hat gesagt, regulaere Ausdruecke waeren einfach - ich bleib
dann einfach dabei, dass der 'Name des Feldes' mit einem ';' abgeschlossen
werden muss. Wozu gibt es Syntaxen, die man definieren kann? ;)

Balu
steffen horst (10.11.2003, 03:05)
Moin

>> längeren |-Konstruktion, aber das wäre unsinnig).

> Gut, genau das habe ich naemlich auch gedacht. Ich war mir nur nicht
> sicher, ob es vielleicht einen speziellen Ausdruck fuer die preg gibt,
> der das erlauben wuerde.


Mmmhm, also da Du ja eine belibige Anzahl von Parametern zulassen willst,
müsstest Du die Klammern schachteln. Und wie das dann ausgewertet wird,
weiss ich nicht. Sonst gibt's ja dafür preg_match_all(), also würde ich
mal annehmen, dass es nicht geht. Aber so schlimm ist's ja auch nicht, die
Paramterliste mit einem zweiten Befehl auszulesen.

> Ich habs die ganze Zeit ohne Klammer versucht: ';?' - das sollte keinen
> Unterschied machen, oder? [...]
> Der betroffene Teilstring wird so erst von der letzten Klammer '(.*?)'
> gematcht. Ich glaube die greedyness springt mir hier in die Quere?


Nee, das macht keinen Unterschied, bis auf die Backreferences. Die
greedyness, ja. Dann nimm einfach die Fragezeichen weg:

preg_match('/<!--\s*Feld\s*:\s*([^;]*)\s*;?\s*(.*)\s*-->/s',
'<!-- Feld : Name des Feldes; param1; param2-->', $matches);

So geht's glaub ich. Ach so, und die Klammern um 'Feld' hab ich wieder
weggemacht :) Wenn das letzte ;-Zeichen wegfällt, sparst Du Dir auch einen
Befehl nach explode() / preg_split(), weil Du nicht mehr testen musst, ob
ein leeres Element am Ende des Arrays ist.

> Tja, niemand hat gesagt, regulaere Ausdruecke waeren einfach - ich bleib
> dann einfach dabei, dass der 'Name des Feldes' mit einem ';'
> abgeschlossen werden muss. Wozu gibt es Syntaxen, die man definieren
> kann? ;)


Vielleicht kommst Du ja doch drum rum..

Gute Nacht,

Steffen
Thomas -Balu- Walter (11.11.2003, 01:34)
In article <opryedb810822tll>, steffen horst wrote:
> Nee, das macht keinen Unterschied, bis auf die Backreferences. Die
> greedyness, ja. Dann nimm einfach die Fragezeichen weg:
> preg_match('/<!--\s*Feld\s*:\s*([^;]*)\s*;?\s*(.*)\s*-->/s',
> '<!-- Feld : Name des Feldes; param1; param2-->', $matches);


wenn ich die ? weg nehme schlaegt die greedyness erst richtig zu und
matcht z.B. einen boese grossen String wenn mehrere der obigen Tags im
Text vorkommen:

<!-- Feld: Name; --> foobar <!-- anderesFeld: Name 2; -->
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

> So geht's glaub ich. Ach so, und die Klammern um 'Feld' hab ich wieder
> weggemacht :) Wenn das letzte ;-Zeichen wegfällt, sparst Du Dir auch einen


Die Klammern brauche ich spaetestens, wenn (Feld|anderesFeld) da stehen
soll :) Ich bastel mir meinen Regex nach dem Lego-Prinzip - Baustein
fuer Baustein :)

> Befehl nach explode() / preg_split(), weil Du nicht mehr testen musst, ob
> ein leeres Element am Ende des Arrays ist.


Balu
steffen horst (11.11.2003, 03:58)
Hallo

> wenn ich die ? weg nehme schlaegt die greedyness erst richtig zu und
> matcht z.B. einen boese grossen String wenn mehrere der obigen Tags im
> Text vorkommen:


Hmm ja, soweit hab ich das nicht getestet. Wie isses damit:

<?

Header("Content-type: text/plain");

preg_match_all('/<!--\s*Feld\s*:\s*([^;]*)\s*;?\s*(.*?)\s*-->/s',
'<!-- Feld : Name des Feldes; param1; param2--> val <!--
Feld:Name2;param1;param2;param3--><!--Feld: moin -->', $matches);

print_r($matches);

?>

Das sieht doch gar nicht so schlecht aus. Und das ';' ist auch noch
optional! :)

> Die Klammern brauche ich spaetestens, wenn (Feld|anderesFeld) da stehen
> soll :) Ich bastel mir meinen Regex nach dem Lego-Prinzip - Baustein
> fuer Baustein :)


Na gut, dann musst Du das oben wieder hinmachen :)

Gute Nacht,

Steffen
Thomas -Balu- Walter (13.11.2003, 16:53)
In article <oprygages8822tll>, steffen horst wrote:
> preg_match_all('/<!--\s*Feld\s*:\s*([^;]*)\s*;?\s*(.*?)\s*-->/s',
> '<!-- Feld : Name des Feldes; param1; param2--> val <!--
> Feld:Name2;param1;param2;param3--><!--Feld: moin -->', $matches);
> Das sieht doch gar nicht so schlecht aus. Und das ';' ist auch noch
> optional! :)


Besten Dank, das sieht tatsaechlich ziemlich gut aus. Jetzt frage ich
mich nur noch, wo diesmal der Haken sein koennte ;) *wuehl*

Balu
Thomas -Balu- Walter (13.11.2003, 17:09)
* Thomas -Balu- Walter wrote:
> In article <oprygages8822tll>, steffen horst wrote:
> Besten Dank, das sieht tatsaechlich ziemlich gut aus. Jetzt frage ich
> mich nur noch, wo diesmal der Haken sein koennte ;) *wuehl*


preg_match('/<!--\s*Feld\s*:\s*([^;]*)\s*;?\s*(.*?)\s*-->/s',
'<!-- Feld : Name des Feldes --> val <!--
Feld:Name2;param1;param2;param3--><!--Feld: moin -->', $matches);

gibt dann Probleme (Match):

"<!-- Feld : Name des Feldes --> val <!--
Feld:Name2;param1;param2;param3-->"

preg_match('/<!--\s*(Feld)\s*:\s*([^;]*?)\s*(;\s*(.*?)\s*)?-->/s',
'<!-- Feld : Name des Feldes --> <!-- Feld: anderers Feld -->',
$matches);

sieht dagegen ganz okay aus. Der Trick ist die zusaetzliche Klammerung
um den "Parameter-Teil", der durch ";" vom Feldnamen getrennt werden
muss und insgesamt optional sein kann.

"Jetzt frage ich mich nur noch, wo diesmal der Haken sein koennte ;) *wuehl*"
-- ich, vor 15 Minuten

:)

Balu
Ähnliche Themen