Вы можете использовать анализатор HTML из lxml, который допускает неправильное вложение, но для этого вам придется заменить квадратные скобки на заостренные и убедиться, что из этого не выйдут никакие невозможные теги HTML, такие как <'>
.
Можно использовать регулярное выражение и выбрать замещающие строки с помощью функции. Не зная вашего целевого формата, я создаю его.
import re
import lxml.html
LINGVO_TAG_EXPR = re.compile(r'\[(\/?)([^\s\]]+)([^]]*)\]')
def lingvo_to_html(match):
groups = match.groups()
is_closing = groups[0] != ''
tag = groups[1].lower()
args = groups[2].strip()
if tag == '*':
htmltag = 'span'
htmlargs = 'class="fulltranslation"'
elif tag == 'm':
htmltag = 'div'
htmlargs = 'class="margin_%s"' % args
elif tag == 'trn':
htmltag = 'div'
htmlargs = 'class="translations"'
elif tag == 'ex':
htmltag = 'div'
htmlargs = 'class="examples"'
elif tag == 'com':
htmltag = 'div'
htmlargs = 'class="comments"'
elif tag == 's':
htmltag = 'div'
htmlargs = 'class="multimedia"'
elif tag == 'url':
htmltag = 'a'
htmlargs = 'href="%s"' % args.replace('"', '"')
elif tag == '!trs':
htmltag = 'span'
htmlargs = 'class="noindex"'
elif tag == 'p':
htmltag = 'div'
htmlargs = 'class="label"'
elif tag == '\'':
htmltag = 'span'
htmlargs = 'class="stressed"'
else:
htmltag = tag
htmlargs = args
if is_closing:
return '</' + htmltag + '>'
else:
return '<' + (htmltag + ' ' + htmlargs).strip() + '>'
def parse_lingvo(dsl_str):
dsl_str = re.sub(LINGVO_TAG_EXPR, lingvo_to_html, dsl_str)
return lxml.html.fromstring(dsl_str)
Добавьте случай elif
для любых отсутствующих тегов. Конечно, вы также можете оставить теги в покое, вместо того, чтобы конвертировать их в <div>
или <span>
.
. Вызывая это следующим образом:
html = parse_lingvo("[tag]text [anothertag]an [']othertext[/'][/tag][/anothertag]")
print(lxml.html.tostring(html))
выводит для меня следующий HTML-код.
b'<tag>text <anothertag>an <span class="stressed">othertext</span></anothertag></tag>'
html
- это lxml Element
, поэтому доступны такие методы, как .xpath()
.