2010-12-09 57 views
0

J'ai un script pour faire une recherche et un remplacement. il est basé sur un script here. Il a été modifié pour accepter le fichier en entrée mais il ne semble pas bien reconnaître regex.Python: remplace les étiquettes mais conserve le texte interne V2

Le script:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import sys, os 
import re 
import glob 

_replacements = { 
    '[B]': '**', 
    '[/B]': '**', 
    '[I]': '//', 
    '[/I]': '//', 

} 

def _do_replace(match): 
    return _replacements.get(match.group(0)) 

def replace_tags(text, _re=re.compile('|'.join((r) for r in _replacements))): 
    return _re.sub(_do_replace, text) 

def getfilecont(FN): 
    if not glob.glob(FN): return -1 # No such file 
    text = open(FN, 'rt').read() 
    text = replace_tags(text, re.compile('|'.join(re.escape(r) for r in _replacements))) 
    return replace_tags(text) 

scriptName = os.path.basename(sys.argv[0]) 
if sys.argv[1:]: 
    srcfile = glob.glob(sys.argv[1])[0] 
else: 
    print """%s: Error you must specify file, to convert forum tages to wiki tags! 
      Type %s FILENAME """ % (scriptName, scriptName) 
    exit(1) 
dstfile = os.path.join('.' , os.path.basename(srcfile)+'_wiki.txt') 
converted = getfilecont(srcfile) 
try: 
    open(dstfile, 'wt+').write(converted) 
    print 'Done.' 
except: 
    print 'Error saving file %s' % dstfile 

print converted 
#print replace_tags("This is an [[example]] sentence. It is [[{{awesome}}]].") 

Ce que je veux est de remplacer

'[B]': '**', 
'[/B]': '**', 

avec une seule ligne comme celui-ci comme dans regex

\[B\](.*?)\[\/B\] : **\1** 

Ce serait très utile avec BBcode des tags comme ceci:

[FONT=Arial]Hello, how are you?[/FONT] 

Ensuite, je peux utiliser quelque chose comme ça

\[FONT=(.*?)\](.*?)\[\/FONT\] : ''\2'' 

Mais je ne peux pas sembler être en mesure de le faire avec ce script. Il y a une autre façon de faire une recherche regex et de la remplacer dans la source originale de ce script, mais cela fonctionne pour une étiquette à la fois en utilisant re.sub. Autre avantage de ce script que je peux ajouter autant de lignes que je veux afin que je puisse le mettre à jour plus tard.

Répondre

1

Pour commencer, vous échapper aux modèles de cette ligne:

text = replace_tags(text, re.compile('|'.join(re.escape(r) for r in _replacements))) 

re.escape prend une chaîne et il échappe de telle sorte que si la nouvelle chaîne ont été utilisés comme regex il correspondre exactement à la chaîne d'entrée.

Retrait de la re.escape ne sera pas tout à fait résoudre votre problème, cependant, vous trouverez ans le remplacement en faisant simplement une recherche du texte correspondant dans votre dict sur cette ligne:

return _replacements.get(match.group(0)) 

Pour résoudre ce problème vous pouvez transformer chaque motif en son propre groupe de capture:

text = replace_tags(text, re.compile('|'.join('(%s)' % r for r in _replacements))) 

Vous devez également savoir quel motif correspond à quelle substitution. Quelque chose comme cela pourrait fonctionner:

_replacements_dict = { 
    '[B]': '**', 
    '[/B]': '**', 
    '[I]': '//', 
    '[/I]': '//', 
} 
_replacements, _subs = zip(*_replacements_dict.items()) 

def _do_replace(match): 
    for i, group in m.groups(): 
     if group: 
      return _subs[i] 

Notez que cela change _replacements dans une liste des motifs, et crée un réseau parallèle _subs pour les remplacements réels. (Je les aurais nommés expressions régulières et remplacements, mais je ne voulais pas avoir à ré-éditer chaque occurrence de "_replacements").

0

Quelqu'un l'a fait here.

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import sys, os 
import re 
import glob 

_replacements_dict = { 
    '\[B\]': '**', 
    '\[\/B\]': '**', 
    '\[I\]': '//', 
    '\[\/I\]': '//', 
    '\[IMG\]' : '{{', 
    '\[\/IMG\]' : '}}', 
    '\[URL=(.*?)\]\s*(.*?)\s*\[\/URL\]' : r'[[\1|\2]]', 
    '\[URL\]\s*(.*?)\s*\[\/URL\]' : r'[[\1]]', 
    '\[FONT=(.*?)\]' : '', 
    '\[color=(.*?)\]' : '', 
    '\[SIZE=(.*?)\]' : '', 
    '\[CENTER]' : '', 
    '\[\/CENTER]' : '', 
    '\[\/FONT\]' : '', 
    '\[\/color\]' : '', 
    '\[\/size\]' : '', 
} 
_replacements, _subs = zip(*_replacements_dict.items()) 

def replace_tags(text): 
    for i, _s in enumerate(_replacements): 
     tag_re = re.compile(r''+_s, re.I) 
     text, n = tag_re.subn(r''+_subs[i], text) 
    return text 


def getfilecont(FN): 
    if not glob.glob(FN): return -1 # No such file 
    text = open(FN, 'rt').read() 
    return replace_tags(text) 

scriptName = os.path.basename(sys.argv[0]) 
if sys.argv[1:]: 
    srcfile = glob.glob(sys.argv[1])[0] 
else: 
    print """%s: Error you must specify file, to convert forum tages to wiki tags! 
      Type %s FILENAME """ % (scriptName, scriptName) 
    exit(1) 
dstfile = os.path.join('.' , os.path.basename(srcfile)+'_wiki.txt') 
converted = getfilecont(srcfile) 
try: 
    open(dstfile, 'wt+').write(converted) 
    print 'Done.' 
except: 
    print 'Error saving file %s' % dstfile 

#print converted 
#print replace_tags("This is an [[example]] sentence. It is [[{{awesome}}]].") 

http://pastie.org/1447448