Faire correspondre les supports imbriqués sans récursion ni groupes d'équilibrage
Défi :
Faire correspondre un ensemble de des crochets arbitrairement imbriqués à l'aide d'une version d'expression régulière qui ne prend pas en charge la récursivité et les groupes d'équilibrage, comme java.util.regex de Java, capturant trois groupes externes dans la chaîne donnée :
(F(i(r(s)t))) ((S)(e)((c)(o))(n)d) (((((((Third)))))))
Solution : transmettre les références à the Rescue
Contrairement à la croyance populaire, faire correspondre les parenthèses imbriquées sans ces fonctionnalités avancées est possible en utilisant des références avancées :
(?=\()(?:(?=.*?\((?!.*?)(.*\)(?!.*).*))(?=.*?\)(?!.*?)(.*)).)+?.*?(?=)[^(]*(?=$)
Décomposer :
Cette regex complexe fonctionne en deux étapes :
Comment ça marche :
Variante de correspondance de groupe interne :
Pour faire correspondre les groupes internes, la stratégie reste la même, mais un groupe de capture est utilisé pour enregistrer le contenu correspondant dans une paire de parenthèses équilibrées :
(?=\()(?=((?:(?=.*?\((?!.*?)(.*\)(?!.*).*))(?=.*?\)(?!.*?)(.*)).)+?.*?(?=)[^(]*(?=$)))
Rupture complète :
Un tableau résume les composants et les fonctionnalités de l'expression régulière :
Note | Component | Description |
---|---|---|
(?=() | Look for '(' | |
(?: | Start group for iteration | |
(?=.?((?!.?1)) | Look for '(' not followed by 1, which contains the matched inner content | |
(.)(?!.2).*)) | Capture inner content and check for at least one more ')' | |
(?=.?)(?!.?3)) | Look for ')' not followed by 2, which contains the matched outer content | |
(. ) | Capture outer content | |
. | Consume a character | |
) | Close group | |
? | Match as few times as possible | |
.*?(?=1) | Match up to and including the last '(' | |
1*(?=2$) | Match up to the last ')' without encountering more '(' |
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!