python正则表达式标记

时间:2011-04-16 02:06:48

标签: python regex expression

我想更改此字符串

<p><b> hello world </b></p>. I am playing <b> python </b>

为:

<bold><bold>hello world </bold></bold>, I am playing <bold> python </bold>

我用过:

import re 

pattern = re.compile(r'\<p>(.*?)\</p>|\<b>(.*?)\</b>')

print re.sub(pattern, r'<bold>\1</bold>', "<p><b>hello world</b></p>. I am playing <b> python</b>")

它没有输出我想要的内容,它抱怨错误:无法匹配的群组

在这种情况下适用:

re.sub(pattern, r'<bold>\1</bold>', "<p>hello world</p>. I am playing <p> python</p>")

<bold> hello world </bold>。我在玩<bold> python</bold>

3 个答案:

答案 0 :(得分:5)

如果您选择不使用正则表达式,那么它很简单:

d = {'<p>':'<bold>','</p>':'</bold>','<b>':'<bold>','</b>':'</bold>'}
s = '<p><b> hello world </b></p>. I am playing <b> python </b>'
for k,v in d.items():
    s = s.replace(k,v)

答案 1 :(得分:3)

虽然我不建议使用Regex来解析HTML(几乎每种语言都有用于此目的的库),但这应该有效:

text = "<p><b> hello world </b></p>. I am playing <b> python </b>"

import re 

pattern1 = re.compile(r'\<p>(.*?)\</p>')
pattern2 = re.compile(r'\<b>(.*?)\</b>')

replaced = re.sub(pattern1, r'<bold>\1</bold>', text)
replaced = re.sub(pattern2, r'<bold>\1</bold>', replaced)

我认为你遇到的问题是因为Python如何使用群组。 测试以下内容,你会明白我的意思:

text = "<p><b> hello world </b></p>. I am playing <b> python </b>"

import re 

pattern = re.compile(r'\<p>(.*?)\</p>|\<b>(.*?)\</b>')

for match in pattern.finditer(text):
  print match.groups()

您将看到以下内容:

('<b> hello world </b>', None) # Here captured the 1st group
(None, ' python ') # Here the 2nd ;)

无论如何,请记住它首先匹配<p></p>之间的匹配,所以它需要<b> hello world </b>(你想要匹配的东西)作为第一个匹配。也许在pattern中编译正则表达式的顺序可以解决这个问题,但可能会发生相反的情况(有<b><p> ... </p></b>

我希望我能提供更多信息,但我在使用Python的正则表达式方面不是很好。 C#采用不同的方式。

修改
我知道您可能希望使用正则表达式进行学习/测试,但不知道,但在生产代码中,我会选择其他替代方案(如@Senthil给你的那个)或只使用HTML Parser

答案 2 :(得分:2)

问题是因为第一组是<p></p>中的一组,而第二组是正则表达式中的<b></b>。但是,在您的替换中,您指的是第一个组,如果它与<b></b>匹配,则没有一个。我提供了几种解决方案。

首先,

>>> pattern = re.compile(r'<(p|b)>(.*?)</\1>')
>>> print re.sub(pattern, r'<bold>\2</bold>', 
                 "<p><b>hello world</b></p>. I am playing <b> python</b>")
<bold><b>hello world</b></bold>. I am playing <bold> python</bold>

将匹配给定的一对标签。但是,正如您所看到的,它必须在字符串上使用两次,因为当它与<p></p>标记匹配时,它会跳过嵌套的<b></b>标记。

以下是我选择的选项:

>>> pattern = re.compile(r'<(/?)[pb]>')
>>> print re.sub(pattern, r'<\1bold>', 
                 "<p><b>hello world</b></p>. I am playing <b> python</b>")
<bold><bold>hello world</bold></bold>. I am playing <bold> python</bold>