regex embedded {{matching

Je dois faire correspondre toute la déclaration suivante:

{{CalendarCustom|year={{{year|{{#time:Y}}}}}|month=08|float=right}} 

En gros, chaque fois qu’il y a un { il doit y avoir un correspondant } quel que soit le nombre de { } incorporés dans la balise d’origine. Ainsi, par exemple {{match}} ou {{ma{{tch}}}} ou {{m{{a{{t}}c}}h}} .

J’ai ça maintenant:

 (\{\{.+?(:?\}\}[^\{]+?\}\})) 

Cela ne fonctionne pas tout à fait.

Le moteur de regex .NET permet une correspondance récursive:

 result = Regex.Match(subject, @"\{ # opening { (?> # now match... [^{}]+ # any characters except braces | # or \{ (?) # a {, increasing the depth counter | # or \} (?<-DEPTH>) # a }, decreasing the depth counter )* # any number of times (?(DEPTH)(?!)) # until the depth counter is zero again \} # then match the closing }", RegexOptions.IgnorePatternWhitespace).Value; 

Je suggère d’écrire un parsingur syntaxique / tokenizer simple pour cela.

En gros, vous passez en boucle sur tous les caractères et commencez à compter les instances de { et } – incrémentant pour { et décrémentant pour } . Enregistrez l’index de chaque premier { et l’index de chaque dernier } et vous obtiendrez les index de vos expressions incorporées.

À ce stade, vous pouvez utiliser une subssortingng pour les obtenir et les supprimer / remplacer de la chaîne d’origine.

Voir cette question et les réponses pour savoir pourquoi RegEx n’est pas adapté.