Je suggère d'utiliser un analyseur capable de gérer de telles structures. L'expression régulière échoue, et c'est correct, car la langue que vous essayez d'analyser n'a pas l'air régulière - du moins à partir des exemples donnés ci-dessus. Chaque fois que vous avez besoin de reconnaître l'imbrication, les expressions rationnelles échoueront ou deviendront des bêtes compliquées comme celle ci-dessus. Même si la langue est régulière, cette expression régulière semble trop compliquée pour moi. Je préfère utiliser quelque chose comme ceci:
def parse_String(string):
index = skip_spaces(string, 0)
index, prefix = read_prefix(string, index)
index = skip_spaces(string, index)
index, attrgroup = read_attrgroup(string, index)
index = skip_spaces(string, index)
index, suffix = read_suffix(string, index)
return prefix, attrgroup, suffix
def read_prefix(string, start_index):
return read_quoted_string(string, start_index)
def read_attrgroup(string, start_index):
end_index, content = read_paren(string, start_index)
index = skip_spaces(content, 0)
index, first_entry = read_quoted_string(content, index)
index = skip_spaces(content, index)
index, second_entry = read_quoted_string(content, index)
return end_index, (first_entry, second_entry)
def read_suffix(string, start_index):
return read_quoted_string(string, start_index)
def read_paren(string, start_index):
return read_delimited_string(string, start_index, '(', ')')
def read_quoted_string(string, start_index):
return read_delimited_string(string, start_index, '"', '"')
def read_delimited_string(string, starting_index, start_limiter, end_limiter):
assert string[starting_index] == start_limiter, (start_limiter
+"!="
+string[starting_index])
current_index = starting_index+1
content = ""
while(string[current_index] != end_limiter):
content += string[current_index]
current_index += 1
assert string[current_index] == end_limiter
return current_index+1, content
def skip_spaces(string, index):
while string[index] == " ":
index += 1
return index
oui, c'est plus de code, et oui, par le nombre brut de clés, cela a pris plus de temps. Cependant - au moins pour moi - ma solution est beaucoup plus facile à vérifier. Cela augmente encore plus si vous supprimez un tas de la plomberie string-and-index en déplaçant tout cela dans la classe, qui analyse ces chaînes dans son constructeur. De plus, il est facile de rendre l'espacement d'espace implicite (en utilisant une méthode magique next-char qui saute juste les caractères jusqu'à ce qu'un non-espace apparaisse, à moins qu'il ne soit dans un mode non-skip dû aux chaînes. la fonction délimitée, par exemple). Cela transformerait la chaîne parse_ en:
def parse_string(string):
prefix = read_prefix()
attrgroup = read_attr_group()
suffix = read_suffix()
return prefix, attrgroup, suffix.
De plus, ces fonctions peuvent être étendues plus facilement pour couvrir des expressions plus compliquées. Attrgroups arbitrairement imbriqués? un changement d'une ligne de code. Parens imbriquées? un peu plus de travail, mais pas de réel problème.
Maintenant, s'il te plaît, flamboie-moi et abats-moi pour être un hérétique et un parseur-plaideur. > :)
PS: oui, ce code n'a pas été testé. comme je me connais, il y a 3 fautes de frappe là-dedans je n'ai pas vu.
Par votre spécification d'entrée, 'attrgroup' contient-il autre chose que des chaînes entre guillemets? –
Bonne question! La réponse est non, ce n'est pas le cas, et ils viennent toujours par deux. –