Le problème est que les langues contenant des parenthèses imbriquées (ou bien quoi que ce soit imbriqué, quoi que ce soit OIEau qui nécessite la récursivité) ne sont pas réguliers, ils sont au moins sans contexte. Cela signifie qu'ils ne peuvent pas être décrits par une grammaire régulière. Les expressions régulières sont une notation compacte pour les grammaires régulières. Ergo, les parenthèses imbriquées ne peuvent pas être décrites par des expressions régulières.
Cependant, nous ne parlons pas d'expressions régulières ici, nous parlons de Regexp
s. Alors que leur sémantique et leur syntaxe sont (très) vaguement basées sur des expressions régulières, elles sont assez différentes et surtout beaucoup plus puissantes. Selon la saveur particulière de Regexp
que vous utilisez, ils peuvent ou non être en mesure d'exprimer la récursivité et donc d'analyser les parenthèses imbriquées. Perl Regex
, par exemple peut parser des parenthèses imbriquées.Je ne suis pas sûr si le Regexp
de Ruby peut, mais je m'en fous vraiment, parce que la façon dont Regexp
est plus puissante que les expressions régulières est généralement accomplie en boulonnant de plus en plus de syntaxe sur eux.
Ceci transforme les expressions régulières, conçues pour être simples, en monstres incompréhensibles. (Si vous pouvez dire en un coup d'oeil ce que le Perl Regex
posté par @Anon fait, alors allez-y, mais je ne peux pas et donc je préfère ne pas l'utiliser.)
Je préfère utiliser un analyseur plus puissant, plutôt que d'un complexe Regexp
.
Dans ce cas, vous disposez d'un langage sans contexte, vous pouvez donc utiliser un analyseur de descente récursif très simple. Vous pouvez encore simplifier votre analyseur de descente récursif en traitant les sous-parties qui sont régulière avec une expression régulière. Enfin, si vous remplacez la récursion dans l'analyseur de descente récursive avec itération + mutation et faire une utilisation intelligente de la sémantique booléennes de Ruby, l'analyseur entier devient essentiellement condensé vers le bas pour cette seule ligne:
while str.gsub!(/\([^()]*?\)/, ''); end
que je ne pense pas est trop mauvais.
est ici la chose entière avec un certain retrait supplémentaire de double espaces et (bien sûr) une suite de tests:
require 'test/unit'
class TestParenthesesRemoval < Test::Unit::TestCase
def test_that_it_removes_even_deeply_nested_parentheses
str = 'This is (was?) some ((heavily) parenthesized (but not overly so
(I hope))) text with (superflous) parentheses:)(.'
res = 'This is some text with parentheses:)(.'
while str.gsub!(/\([^()]*?\)/, ''); end
str.squeeze!(' ')
assert_equal res, str
end
end
s'il y a un nombre inégal de balises d'ouverture et de fermeture comme dans '(foo) bar) 'ou s'il n'y a pas de paires comme dans' foo) (bar'? – Gumbo
Je n'ai pas besoin de rendre compte de ce scenerio – TenJack