4 votes

PHP : regex pour correspondre aux parenthèses complètes ?

En PHP, j'ai la chaîne suivante :

 $text = "test 1
          {blabla:database{test}}
          {blabla:testing}
          {option:first{A}.Value}{blabla}{option:second{B}.Value}
          {option:third{C}.Value}{option:fourth{D}}
          {option:fifth}
          test 2
         ";

J'ai besoin d'obtenir tous les { option ...} de cette chaîne (5 au total dans cette chaîne). Certains ont plusieurs parenthèses imbriquées, d'autres non. Certains sont sur la même ligne, d'autres non.

J'ai déjà trouvé cette regex :

(\{(?>[^{}]+|(?1))*\})

Le texte suivant fonctionne bien :

preg_match_all('/(\{(?>[^{}]+|(?1))*\})/imsx', $text, $matches);

Le texte qui ne se trouve pas à l'intérieur des accolades est filtré, mais les correspondances incluent également les éléments suivants blabla -dont je n'ai pas besoin.

Existe-t-il un moyen de modifier cette expression pour qu'elle n'inclue que les éléments suivants option -des articles ?

1voto

Leigh Points 8802

Ce problème est bien mieux adapté à un analyseur syntaxique approprié, mais vous pouvez le faire avec une expression rationnelle si vous le voulez vraiment.

Cela devrait fonctionner tant que vous n'intégrez pas d'options dans d'autres options.

preg_match_all(
    '/{option:((?:(?!{option:).)*)}/',
    $text,
    $matches,
    PREG_SET_ORDER
);

Explication rapide.

{option:               // literal "{option:"
  (                    // begin capturing group
    (?:                // don't capture the next bit
      (?!{option:).    // everything NOT literal "{option:"
    )*                 // zero or more times
  )                    // end capture group
}                      // literal closing brace

var_dump Le résultat de l'analyse avec votre exemple d'entrée ressemble à ceci :

array(5) {
  [0]=>
  array(2) {
    [0]=>
    string(23) "{option:first{A}.Value}"
    [1]=>
    string(14) "first{A}.Value"
  }
  [1]=>
  array(2) {
    [0]=>
    string(24) "{option:second{B}.Value}"
    [1]=>
    string(15) "second{B}.Value"
  }
  [2]=>
  array(2) {
    [0]=>
    string(23) "{option:third{C}.Value}"
    [1]=>
    string(14) "third{C}.Value"
  }
  [3]=>
  array(2) {
    [0]=>
    string(18) "{option:fourth{D}}"
    [1]=>
    string(9) "fourth{D}"
  }
  [4]=>
  array(2) {
    [0]=>
    string(14) "{option:fifth}"
    [1]=>
    string(5) "fifth"
  }
}

0voto

ryanbwork Points 1506

J'ai modifié votre expression initiale pour rechercher la chaîne de caractères '(option :)' complétée par des caractères autres que des espaces ( \S *), délimités par des accolades '{}'.

\{(option:)\S*\}

Étant donné votre texte d'entrée, les entrées suivantes sont mises en correspondance dans regexpal :

test 1

{blabla:database{test}}

{blabla:testing}

{option:first{A}.Value} {option:second{B}.Valeur}

{option:troisième{C}.Valeur}

{option:quatrième{D}}

{option:cinquième}

test 2

0voto

Rui Jarimba Points 3243

Essayez cette expression régulière - elle a été testée à l'aide d'expressions régulières .NET, mais elle peut également fonctionner avec PHP :

\{option:.*?{\w}.*?}

Veuillez noter que je suppose que vous n'avez qu'une seule paire de parenthèses à l'intérieur, et qu'à l'intérieur de cette paire vous n'avez qu'un seul caractère alphanumérique.

0voto

abc667 Points 436

Si vous n'avez pas plusieurs paires de parenthèses au même niveau, cela devrait fonctionner.

/(\{option:(([^{]*(\{(?>[^{}]+|(?4))*\})[^}]*)|([^{}]+))\})/imsx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X