2017-03-03 2 views
2

J'ai quelques cas de test:

Bad:motif de match que si entre parenthèses

1 + 2 
(3 + 4) + 5 
(1 + 2) + (3 + 4) 

Bon:

(1 + 2) 
((3 + 4) + 5) 
((1 + 2) + (3 + 4)) 

Je veux une expression régulière qui correspond à quelque chose entre parenthèses. Fondamentalement, s'il y a quelque chose en dehors des parenthèses, c'est mauvais. Vous devez supposer que la chaîne a toujours raison, donc vous n'avez pas à compter les parenthèses de départ et de fermeture.

J'ai essayé de faire ce qui suit: ^\(.*\)$

Cela correspond également (1 + 2) + (6 + 7) ce qui est mauvais et je ne sais pas comment le faire Beter.

Répondre

4

Vous pouvez utiliser un regex avec un subroutine call qui correspond imbriqué (...) récursive:

^(\((?:[^()]++|(?1))*\))$ 

Voir la regex demo

Détails:

  • ^ - début de la chaîne (peut être remplacé par \A, pour assurer la correspondance g début de la chaîne uniquement)
  • (\((?:[^()]++|(?1))*\)) - Capture groupe 1 qui sera récursifs correspondant à:
    • \( - un ( littérales
    • (?:[^()]++|(?1))* - zéro ou plusieurs occurrences de:
      • [^()]++ - 1+ caractères autres que ( et ) (appariés possessivement pour interdire le retour arrière dans le motif)
      • | - ou
      • (?1) - appel de sous-programme qui récursivement groupe 1 motif
    • \) - un littéral )
  • $ - fin de chaîne (pour correspondre à la fin d'une chaîne, utilisez \Z, ou la fin de chaîne peut être associé à \z)

Notez que (?R) construction ca Ne pas être utilisé ici, car il serait recurse le motif entier, et les ancres (^ et $) échouerait toutes les correspondances à l'intérieur de la chaîne.

+0

La meilleure réponse de la semaine vous revient. – Bathsheba

+0

Battre mon temps d'une seconde, je devrais absolument augmenter ma vitesse de frappe. –

+0

Il n'y aurait aucun mal à écrire une réponse plus longue avec une description caractère par caractère de l'expression régulière. – Bathsheba