2010-03-04 5 views
0
[quote=Username here]quoted text here[/quote] 

Reply text here 

J'ai besoin d'une expression régulière qui stocke "Nom d'utilisateur ici", "texte cité ici" et "Texte de réponse ici" dans un tableau.Problème Regex (PHP)

Cette expression doit également prendre en charge l'imbrication. EKS:

[quote=Username2 here][quote=Username here]quoted text here[/quote] 

Reply text here[/quote] 

Reply text here 
+2

Ils ne sont pas assez puissants. Vous devriez penser à écrire un analyseur syntaxique basé sur une pile qui peut effectuer une imbrication arbitraire en profondeur. –

+0

Quelle est la sortie désirée de l'exemple imbriqué? Y a-t-il une limite à la profondeur de l'imbrication des guillemets? – Jens

Répondre

0

En supposant que vous ne voulez pas retourner les valeurs imbriquées d'une manière ou avec des guillemets appariés - qui sont impossibles dans un regex - vous pouvez simplement diviser sur les pièces que vous n'avez pas besoin:

preg_split('/(\[quote=|\[quote]|]|\[/quote])/', $yourstring); 
+0

Cela ne correspond pas aux blocs de citation imbriqués arbitraires. –

+0

Comme je l'ai dit: certaines choses que vous ne pouvez pas faire dans une expression régulière. Correspondant à la nidification est une telle chose. Très injuste de soustraire des points quand je ne peux pas vous rendre mathématiquement impossible. – Matijs

+0

Toutes mes excuses, je pensais que vous aviez posté une solution 'preg_match (...)', je vois maintenant que c'était un 'preg_split (...)'. Je vais retirer mon vote négatif. –

3

Ce regex correspond à bloc de guillemets imbriqués (dans le groupe 1) avec une dernière réponse supplémentaire (dans le groupe 2):

(\[quote=[^]]*](?:(?R)|.)*\[/quote])(.*) 

une petite démo:

$text = '[quote=Username2 here][quote=Username here]quoted text[/quote]Reply text[/quote]More text'; 
preg_match('#(\[quote=[^]]*](?:(?R)|.)*\[/quote])(.*)#is', $text, $match); 
print_r($match); 

produit:

Array 
(
    [0] => [quote=Username2 here][quote=Username here]quoted text[/quote]Reply text[/quote]More text 
    [1] => [quote=Username2 here][quote=Username here]quoted text[/quote]Reply text[/quote] 
    [2] => More text 
) 

Une petite explication:

(     # open group 1 
    \[quote=[^]]*] # match '[quote= ... ]' 
    (?:(?R)|.)*  # recursively match the entire pattern or any character and repeat it zero or more times 
    \[/quote]  # match '[/quote]' 
)     # open group 1 
(     # open group 2 
    .*    # match zero or more trailing chars after thae last '[/quote]' 
)     # close group 2 

Mais, en utilisant ces constructions regex récursives supportés par PHP pourrait faire les tourner la tête ... J'opterais un peu analyseur comme John Kugelman suggéré. Les expressions régulières ne font pas d'imbrication.