Python中的正则表达式排除
我不能用正则表达式,我正在寻找排除某些东西的语法。 我解析<
,>
,"
和&
在html代码(用<
等取代),我需要排除<br/>
从解析。 即:Python中的正则表达式排除
<html><br/>
<head><title></title></head><br/>
<body><br/>
</body><br/>
</html>
我试着像sometihng即:r'<\b?![br]'
等人,但他们并不完全工作。我用re.sub()
来代替。
好了,现在的问题是重新开放,我可以做到这一点作为一个答案,所以......
除非我失去了一些东西,而一旦它只是<br/>
(没有任何变体),则可以只替换<(?!br/>)
与<
和(?<!<br/)>
与>
这就是它?
在Python,它看起来像这意味着这样的:
text = re.sub('<(?!br/>)' , '<' , text)
text = re.sub('(?<!<br/)>' , '>' , text)
为了解释这是怎么回事,(?!
...... )
是负前瞻 - 它只有在成功当一个位置相匹配以下文字不是与其包含的子表达式匹配。
(注向前看符号不消耗由他们的子表达式匹配的文本,他们只当它不存在,或者无法核实。)
同样,(?<!
... )
是负的样子背后和做同样的事情,但使用前面的文字。
但是,lookbeheads与lookaheads(在一些正则表达式实现中)略有不同 - 也就是说,lookbehinds内部的子表达式必须表示固定宽度或有限宽度的匹配。
Python是需要固定宽度的那个 - 所以虽然上面的表达式工作(因为它总是四个字符),如果它是(?<!<br\s*/?)>
那么它不会是Python的有效正则表达式,因为它表示一个可变长度比赛。 (但是,可以将堆叠多个向后看,所以如果需要,您可以手动迭代各种选项。)
替换一切,然后在第二遍替换“& lt; br/& gt;”与“< br/>”。
或者,为了一般化,有一个你想'恢复'的标签列表并替换为“& lt; tag & gt;”与“<标记>”,“& lt;/tag & gt;”与“< /标记>”和“& lt; tag/& gt;” “< tag/>”。
这是否对应您需要的?:
import re
import htmlentitydefs
ss = '''
<html>
<br>
<title>"War & Peace"</title>
<body>Leon Tolstoy</body>
<br/>
</html>'''
print ss
print '\n\n'
uniquechars_repl = '"&'
conditional_repl = {'<':'<(?!br/>)',
'>':'(?<!<br/)>'}
all_repl = list(uniquechars_repl) + conditional_repl.keys()
di = dict((b,'&%s;' % a) for a,b in htmlentitydefs.entitydefs.iteritems()
if b in all_repl)
pat = '|'.join(list(uniquechars_repl) + conditional_repl.values())
text = re.sub(pat , lambda mat: di[mat.group()], ss)
print text
结果
<html>
<br>
<title>"War & Peace"</title>
<body>Leon Tolstoy</body>
<br/>
</html>
<html>
<br>
<title>"War & Peace"</title>
<body>Leon Tolstoy</body>
<br/>
</html>
我不能也不想安装外部库。 – stdio
@stdio你不需要外部库; Python附带了开箱即用的ElementTree(lxml提供了更好的实现的API)。 –
XML(像它扩展的SGML)不是一种常规语言(在计算机科学中这个术语的含义 - 如果你已经参加了编译器设计课程,他们应该进入它)。正则表达式不足以解析它。 –