2009-07-06 13 views
1

Ich versuche nur meine Hand bei der Herstellung meiner allerersten Regex. Ich möchte ein Pseudo-HTML-Element entsprechen zu können und nützliche Informationen wie Tag-Namen extrahieren, Attribute etc .:PHP RegEx Grouping Mehrere Treffer

$string = '<testtag alpha="value" beta="xyz" gamma="abc" >'; 

if (preg_match('/<(\w+?)(\s\w+?\s*=\s*".*?")+\s*>/', $string, $matches)) { 
    print_r($matches); 
} 

Außer, ich bin immer:

Array ([0] => [1] => testtag [2] => gamma="abc") 

Wer weiß, wie kann ich Bekomme die anderen Attribute? Was vermisse ich?

+1

Ihre allererste Regex sollte nicht für übereinstimmenden HTML/XML sein, da dies die eine Sache ist, die Regex wirklich schlecht sind. Glauben Sie mir, sie saugen es, und Sie sollten es vermeiden, sie von Anfang an dafür zu benutzen. – Tomalak

+0

Aber Sie müssen zugeben, es ist ein guter Weg, um ihre Grenzen zu lernen. ;) –

+0

Wahrscheinlich, ja. ;-) Es ist einfach, mit Regex eine "alles geht" -Antwicklung zu entwickeln, die Sie glauben lässt, dass alles, was als Text * dargestellt wird, * Text ist. XML und HTML sind keine Texte, sie sind strukturierte Daten und sollten mit Datenwerkzeugen und nicht mit Textwerkzeugen verarbeitet werden. Die beste Zeit, um die Warnung zu präsentieren, ist, wenn jemand gerade mit Regex beginnt. :) – Tomalak

Antwort

3

diesem regulären Ausdruck Versuchen:

/<(\w+)((?:\s+\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s]*))*)\s*>/ 

Aber Sie sollten wirklich nicht reguläre Ausdrücke für eine kontextfreie Sprache wie HTML verwenden. Verwenden Sie stattdessen einen echten Parser.

+0

Möchten Sie näher erläutern, was Sie meinen "echten Parser" meinen? –

+2

@Tim Lytle: Regexes sind keine Parser. Sie sind höchstens Teil von Parsern *. Ein realer Parser ist beispielsweise ein XML-DOM-Parser - er kann Sprachen parsen, während Regexes nur Muster finden können. – Tomalak

+0

@Tomalak Ah, habe nicht verstanden, was er meinte. Macht jetzt vollkommen Sinn. –

0

Ihre zweite Erfassungsgruppe übereinstimmt, die Attribute zu einer Zeit, jedes Mal der vorherigen überschrieben werden. Wenn Sie .NET-Regexe verwenden, können Sie das Captures-Array verwenden, um die einzelnen Captures abzurufen, aber ich kenne keinen anderen Regex-Flavor mit dieser Funktion. Normalerweise müssen Sie so etwas wie alle Attribute in einer Gruppe erfassen und dann einen anderen regulären Ausdruck für den erfassten Text verwenden, um die einzelnen Attribute auszubrechen.

Dies ist der Grund, warum Menschen entweder Regexe lieben oder hassen sie (oder beides). Sie können einige wirklich erstaunliche Dinge mit ihnen tun, aber Sie laufen auch in einfache Aufgaben wie diese, die lächerlich hart, wenn nicht unmöglich sind.