2009-05-22 4 views
3

Okay donc j'ai un problème semi-weridish avec re.sub.Sous-problèmes d'expression régulière

Prenez le code suivant:

import re 
str_to_be_subbed = r'somefile.exe -i <INPUT>' 
some_str = r'C:\foobar' 
s = re.sub(r'\<INPUT\>', some_str, str_to_be_subbed) 
print s 

Je pense qu'il me donnerait:

somefile.exe -i C:\\foobar 

Mais au lieu de cela me donne:

somefile.exe -i C:♀oobar 

Je sais que \ f est un échapper à l'omble, mais même si j'essaie de le faire de cette façon, ce qui devrait échapper aux caractères spéciaux. Même si je fais ceci:

print r'%s' % s 

Il me donne encore ceci:

somefile.exe -i C:♀oobar 

Pourquoi fait-il cela? Et quel est le meilleur moyen d'éviter cela?

Ninja Edit:

Si je regarde la valeur de s est:

'somefile.exe -i C:\x0coobar' 

Pourquoi a fait \ tour f dans \ x0. Pouah.

Edit:

une question, si je modifie le code à ceci:

import re 
import os 
str_to_be_subbed = r'somefile.exe -i <INPUT>' 
some_str = os.path.abspath(r'C:\foobar') 
some_str 
s = re.sub(r'\<INPUT\>', some_str, str_to_be_subbed) 
print s 

Donne-moi:

>>> import re 
>>> import os 
>>> str_to_be_subbed = r'somefile.exe -i <INPUT>' 
>>> some_str = os.path.abspath(r'C:\foobar') 
>>> some_str 
'C:\\foobar' 
>>> s = re.sub(r'\<INPUT\>', some_str, str_to_be_subbed) 
>>> print s 
somefile.exe -i C:♀oobar 

Maintenant, pourquoi est-ce. Depuis os.path.abspath échappe les \ 's. Pourquoi re.sub encore gâcher?

Il s'agit également d'un très petit exemple, de ce petit problème qui vient de surgir au hasard dans une application ancienne. Je ne peux pas vraiment aller et changer cela à string.replace à cause de comment sa configuration sans passer une journée entière.

Je suis juste vraiment curieux de savoir pourquoi il le fait. Pour le problème ci-dessus.

Répondre

3

\f est le flux de formulaire caractère. Échapper et cela fonctionne:

some_str = r'C:\\foobar' 

Une autre solution:

s = re.sub(r'<INPUT>', some_str.encode("string_escape"), str_to_be_subbed) 
+0

Merci. Encode fonctionne étonnamment. – UberJumper

3

Ne pas utiliser des expressions régulières:

print str_to_be_subbed.replace("<INPUT>",some_str) 

Comme le documentation dit:

rempl peut être une chaîne ou une fonction; si il s'agit d'une chaîne, toutes les échappées sont traitées.

+0

Je ne peux pas utiliser de chaîne remplacer. Je dois utiliser la forme regex sinon je serai obligé de changer/modifier des centaines de lignes de code de quelqu'un d'autre. – UberJumper

0

Votre exemple n'a pas besoin regexps, utilisez str.replace():

>>> str_to_be_subbed.replace('<INPUT>',some_str) 
'somefile.exe -i C:\\foobar' 
>>> 
2

docs Python dire ...

re.sub (modèle, rempl, chaîne, n = 0, drapeaux = 0) Renvoie la chaîne obtenue en remplaçant les occurrences non chevauchantes les plus à gauche du motif dans la chaîne par le repl repl. Si le motif n'est pas trouvé, la chaîne est retournée inchangée. repl peut être une chaîne ou une fonction; S'il s'agit d'une chaîne, toutes les fuites d'antislash qui s'y trouvent sont traitées. C'est-à-dire \ n est converti en un seul caractère de nouvelle ligne, \ r est converti en un retour chariot, et ainsi de suite. Les échappées inconnues telles que \ j sont laissées à elles seules

C'est pourquoi il donne 'C: ♀obar'. Mais si nous lui donnons une fonction comme deuxième argument, il ne convertit aucune barre oblique inverse (backslash).

Donc, essayez la suite ..

>>>import re 
>>>str_to_be_subbed = r'somefile.exe -i <INPUT>' 
>>>some_str = r'C:\foobar' 
>>>s = re.sub(r'\<INPUT\>', lambda _:some_str, str_to_be_subbed) 
>>>print s 
somefile.exe -i c:\foobar