10
votes

Python Expression régulière remplaçant une partie d'une chaîne assortie

J'ai une chaîne qui pourrait ressembler à ce xxx pré>

Je vérifie actuellement la validité en utilisant, ce qui fonctionne bien p> xxx pré>

J'aimerais maintenant remplacer la chaîne du 3ème paramètre. Malheureusement, je ne peux pas simplement utiliser un stringreplace sur n'importe quelle sous-chaîne de la 3e position depuis la même "sous-chaîne" pourrait être ailleurs ailleurs dans cette chaîne. P>

avec ceci et un re.findall, P >

myRe = re.compile(r"myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)")
val =   "myFunc('element','node','elementVersion','ext',12,0,0)"

print myRe.findall(val)
print myRe.sub("noVersion",val)


1 commentaires

La variété de réponses me conduit ici de croire que la révolte pythonique contre la devise Timtowtdi de Perl était quelque peu égarée. :)


5 Réponses :


1
votes

Avez-vous essayé d'utiliser des groupes nommés? http://docs.python.org/howto/regex.html#search -et-remplacer

Espérons que cela vous permettra de cibler le 3ème match.


0 commentaires

1
votes

Si vous voulez le faire sans utiliser Regex:

>>> s = "myFunc('element','node','elementVersion','ext',12,0,0)"
>>> l = s.split(",")
>>> l[2]="'noVersion'"
>>> s = ",".join(l)
>>> s
"myFunc('element','node','noVersion','ext',12,0,0)"


4 commentaires

Et si la première Arg est "élément"?


Ensuite, toutes les réponses, y compris les expressions ordinaires, échouent. :)


vous avez raison! C'est pourquoi je pense qu'un analyseur convient parfaitement à cette tâche qu'une expression régulière.


@Paulo, oui, des analyseurs, si disponibles pour le travail à portée de main, devrait être préféré surgex.



9
votes

in Re2, vous devez spécifier une substitution pour toute la chaîne de correspondance. Cela signifie que vous devez répéter les pièces que vous ne voulez pas remplacer. Cela fonctionne:

myRe = re.compile(r"(myFunc\(.+?\,.+?\,)(.+?)(\,.+?\,.+?\,.+?\,.+?\))")
print myRe.sub(r'\1"noversion"\3', val)


0 commentaires

4
votes

Si votre seul outil est un marteau, tous les problèmes ressemblent à des ongles. Une expression régulière est un marteau puissant mais n'est pas le meilleur outil pour chaque tâche.

Certaines tâches sont mieux gérées par un analyseur. Dans ce cas, la liste des arguments de la chaîne est comme un tuple Python, Sou vous pouvez tricher: Utilisez l'analyseur intégré Python: xxx

si vous ne pouvez pas faire confiance à l'entrée ast.literal_eval est plus sûr que l'évaluation de cet objectif. Une fois que vous avez la liste des arguments dans la chaîne décontruite, je pense que vous pouvez déterminer comment manipuler et remonter à nouveau, si nécessaire.


0 commentaires

2
votes

Lire la documentation: re.sub code> renvoie une copie de la chaîne lorsque chaque occurrence de l'ensemble du motif est remplacée par le remplacement. Il ne peut en aucun cas modifier la chaîne d'origine, car les chaînes Python sont immuables.

Essayez d'utiliser des assertions de look-avance et de look-derrière pour construire une regex qui correspond uniquement à l'élément lui-même: P>

myRe = re.compile(r"(?<=myFunc\(.+?\,.+?\,)(.+?)(?=\,.+?\,.+?\,.+?\,.+?\))")


1 commentaires

S'il y a une chance d'un argument contenant une virgule, l'approche de regex devient plus difficile et plus difficile.