Python: заменить теги, но сохранить внутренний текст V2 - PullRequest
0 голосов
/ 09 декабря 2010

У меня есть скрипт для поиска и замены. он основан на скрипте здесь . Он был изменен, чтобы принимать файл в качестве входных данных, но, похоже, он плохо распознает регулярные выражения.

Сценарий:

#!/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}}]].")  

То, что я хочу, это заменить

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

только с одной строкой, как в регулярном выражении

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

Это очень полезно для BBcode-тегов, таких как:

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

Тогда я могу использовать что-то вроде этого

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

Но я не могу сделать это с помощью этого сценария. Существуют и другие способы поиска и замены регулярных выражений в исходном коде этого скрипта, но он работает для одного тега за раз, используя re.sub. Другое преимущество этого скрипта в том, что я могу добавить столько строк, сколько захочу, чтобы я мог обновить его позже.

Ответы [ 2 ]

1 голос
/ 09 декабря 2010

Для начала вы избегаете шаблонов в этой строке:

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

re.escape берет строку и экранирует ее таким образом, что если бы новая строка использовалась в качестве регулярного выражения, она быточно соответствует входной строке.

Удаление re.escape не решит полностью вашу проблему, однако, и вы найдете замену, просто выполнив поиск совпадения текста в вашем dict в этой строке:

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

Чтобы исправить это, вы можете превратить каждый шаблон в отдельную группу захвата:

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

Вам также необходимо знать, какой шаблон подходит для какой замены.Примерно так может работать:

_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]

Обратите внимание, что это превращает _replacements в список шаблонов и создает параллельный массив _subs для фактических замен.(Я бы назвал их регулярными выражениями и заменами, но не хотел бы пересматривать каждое вхождение «_replacements»).

0 голосов
/ 11 января 2011

Кто-то сделал это здесь .

#!/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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...