2009-03-04 7 views
2

Ich verwende derzeit 3 ​​verschiedene reguläre Ausdrücke in einem preg_match, indem ich das oder -Zeichen | um sie zu trennen. Das funktioniert perfekt. Der erste und der zweite Regex haben jedoch den gleichen Ausgabetyp. z.B. [0] Quelltext [1] Zahl Betrag [2] Name - jedoch der letzte, da es eine andere Anordnung von Quelltext verwendet: [0] Quelltext [1] Name [2] Anzahl Betrag.Knifflige Frage: Wie man Ergebnisse von mehreren Regexes anordnet

preg_match('/^Guo (\d+) Cars @(\w+)|^AV (\d+) Cars @(\w+)|^@(\w+) (\d+) [#]?av/i', $source, $output); 

Da Name der Lage ist, numerisch sein ich nicht eine einfache Prüfung tun können, um zu sehen, ob es numerisch ist. Gibt es einen Weg, ich kann entweder die Reihenfolge in der Regex oder identifizieren, welche Regex es auch abgestimmt. Geschwindigkeit ist hier von entscheidender Bedeutung, also wollte ich nicht 3 separate preg_match-Anweisungen verwenden (und weitere werden folgen).

Antwort

3

Drei separate reguläre Ausdrücke langsamer nicht müssen. Eine große Aussage wird eine Menge Backtracing für die Engine für reguläre Ausdrücke bedeuten. Der Schlüssel zur Optimierung von regulären Ausdrücken ist, dass die Engine so schnell wie möglich fehlschlägt. Haben Sie ein Benchmarking durchgeführt, um sie zu ziehen?

In Ihrem Fall können Sie nutzen die PCRE ‚s benannte Captures (?<name>match something here) und ersetzen mit ${name} statt \1 machen. Ich bin nicht 100% sicher, dass dies für preg_replace funktioniert. Ich weiß, preg_match speichert korrekt Captures für bestimmte, obwohl.

PCRE muss mit der Option PCRE_DUPNAMES kompiliert werden, damit sie in Ihrem Fall (wie in RoBorgs) nützlich ist. Ich bin nicht sicher, ob die kompilierte PCRE-DLL-Datei von PHP diese Option hat.

+0

Hallo Martijn, Vielen Dank für Ihre Antwort, Sie haben Recht die PCRE nicht mit der DUPNAMES Option hier zusammengestellt Sinn kann ich nicht Verwenden Sie die gleichen Gruppennamen. Ich war mir nicht bewusst, dass separate REGEX könnte schneller sein. Ich habe dort noch kein Benchmarking durchgeführt. – Ice

3

Sie benannte Capture-Gruppen verwenden:

preg_match('/^Guo (?P<number_amount>\d+) Cars @(?P<name>\w+)|^AV (?P<number_amount>\d+) Cars @(?P<name>\w+)|^@(?P<name>\w+) (?P<number_amount>\d+) [#]?av/i', $source, $output); 
0

Ich weiß nicht, seit welcher Version PCRE die duplicate subpattern numbers syntax (?| …) unterstützt. Aber versuchen Sie diesen regulären Ausdruck:

/^(?|Guo (\d+) Cars @(\w+)|AV (\d+) Cars @(\w+)|@(\w+) (\d+) #?av)/i 

So:

$source = '@abc 123 av'; 
preg_match('/^(?|Guo (\\d+) Cars @(\\w+)|AV (\\d+) Cars @(\\w+)|@(\\w+) (\\d+) #?av)/i', $source, $output); 
var_dump($output); 
Verwandte Themen