考虑以下字符串(编辑:这不是带有正则表达式问题的解析HTML。而只是带有命名组的练习):
s = """<T1>
<A1>
lorem ipsum
</A1>
</T1>"""
是否可以使用re.sub
和命名组将字符串转换为此结果?
<T1>
<test number="1">
lorem ipsum
</test>
</T1>
现在我有以下代码:
import re
regex = re.compile("(<(?P<end>\/*)A(?P<number>\d+)>)")
print regex.sub('<\g<end>test number="\g<number>">', s)
给出以下结果
<T1>
<test number="1">
lorem ipsum
</test number="1">
</T1>
可以像question一样使用|
运算符吗?
答案 0 :(得分:1)
x="""<T1>
<A1>
lorem ipsum
</A1>
</T1>"""
def repl(obj):
if obj.group(1):
return '/test'
else:
return 'test number="'+obj.group(2)+'"'
print re.sub(r"(\/*)A(\d+)",repl,x)
您可以发送re.sub
提供的替换功能。
答案 1 :(得分:1)
尝试匹配整个标记。不仅是打开和关闭标签,还要抓住它的内容。
正则表达式:
(<(?P<end>\/*)(A)(?P<number>\d+)>)(.*?)</\3\4>
更换字符串:
<test number="\g<number>">\5</test>
>>> s = """<T1>
<A1>
lorem ipsum
</A1>
</T1>"""
>>> import re
>>> print(re.sub(r'(?s)(<(?P<end>\/*)(A)(?P<number>\d+)>)(.*?)</\3\4>', r'<test number="\g<number>">\5</test>', s))
<T1>
<test number="1">
lorem ipsum
</test>
</T1>
(?s)
调用了DOTALL修饰符,它匹配你的正则表达式中的点以匹配偶数换行符。
答案 2 :(得分:1)
您可以使用环视匹配来匹配<T1>
和</T1>
之间的字符串:
>>> p = re.compile(ur'(?<=<T1>)[^<]+?(.+)(?=</T1>)', re.MULTILINE | re.IGNORECASE | re.DOTALL)
>>> s2='\n <test number="1">\n lorem ipsum\n </test>\n'
>>> print p.sub(s2,s,re.MULTILINE)
<T1>
<test number="1">
lorem ipsum
</test>
</T1>
您需要使用以下Contents:
<强> re.IGNORECASE 强> 执行不区分大小写的匹配;像[A-Z]这样的表达式也会匹配小写字母。这不受当前区域设置的影响。
<强> re.MULTILINE 强> 指定时,模式字符'^'匹配字符串的开头和每行的开头(紧跟在每个换行符之后);并且模式字符'$'在字符串的末尾和每行的末尾(紧接在每个换行符之前)匹配。默认情况下,'^'仅匹配字符串的开头,'$'仅匹配字符串的结尾,紧接在字符串末尾的换行符(如果有)之前。
<强> re.DOTALL 强> 制作'。'特殊字符匹配任何字符,包括换行符;没有这个标志,'。'将匹配除换行符之外的任何内容。