Python re.findall

时间:2013-11-16 15:33:11

标签: python regex python-2.7

我正在尝试检索包含“名称”字段的所有标记,然后将整个句子加上名称。 这是我的测试代码:

sourceCode = '<dirtfields name="one" value="stuff">\n<gibberish name="two"\nwewt>'
namesGroup = re.findall('<.*name="(.*?)".*>', sourceCode, re.IGNORECASE | re.DOTALL)

for name in namesGroup:
    print name

哪个输出是:

two

我想要寻找的输出是

['<dirtfields name="one" value="stuff">', 'one']
['<gibberish name="two"\nwewt>', 'two']

编辑: 找到了一种方法,感谢doublesharp获得“名称”值的更简洁方法。

namesGroup = re.findall(r'(<.*?name="([^"]*)".*?>)', sourceCode, re.IGNORECASE | re.DOTALL)

将输出:

('<dirtfields name="one" value="stuff">', 'one')
('<gibberish name="two"\nwewt>', 'two')

4 个答案:

答案 0 :(得分:3)

你的正则表达式有点偏 - 你匹配太多(一直到最后>)。由于您只需要在name=之后使用双引号之间的值,使用以下模式:

name="([^"]*)"
  • name="匹配您要查找的属性的第一部分
  • ([^"]*)根据双引号
  • 的任何字符创建分组匹配
  • "匹配name属性值后的双引号。

您的代码看起来像这样(在您的模式之前包含r是一种很好的形式):

namesGroup = re.findall(r'name="([^"]*)"', sourceCode, re.IGNORECASE)

答案 1 :(得分:3)

显然,您正在处理HTMLXML文件并查找特定属性的某些值。

如果你继续使用正则表达式而不是合法的文本解析器,你会犯一个方向错误。

与我最喜欢的BeautifulSoup4一样,这是一个如何使用它的简短示例:

from bs4 import BeautifulSoup

sourceCode = '<dirtfields name="one" value="stuff">\n<gibberish name="two"\nwewt>'

soup = BeautifulSoup(sourceCode)
print soup.prettify()
print '------------------------'
for tag in soup.find_all():
    if tag.has_key('name'):
        print tag, tag['name']

输出看起来有点难看(输出甚至是错误的),但是这表明beautifulsoup会自动修复你的破坏的html并轻松找到你想要的属性。

<html>
 <body>
  <dirtfields name="one" value="stuff">
   <gibberish name="two" wewt="">
   </gibberish>
  </dirtfields>
 </body>
</html>
------------------------
<dirtfields name="one" value="stuff">
<gibberish name="two" wewt=""></gibberish></dirtfields> one
<gibberish name="two" wewt=""></gibberish> two

Beautifulsoup添加到您最喜爱的Stackoverflow标签中,您会惊讶地发现它有多好,以及有多少人使用更强大的工具与您做同样的事情!

答案 2 :(得分:2)

(?<=name=")[^"]*

如果您只想匹配没有捕获组的名称,可以使用:

re.findall(r'(?<=name=")[^"]*', sourceCode, re.IGNORECASE )

输出: ['one', 'two']

当然,捕获组是同样可接受的解决方案。

答案 3 :(得分:0)

这是一种允许在值内部使用转义引号并避免(出于性能原因)延迟量词的模式。这就是为什么它有点长但更防水的原因:

myreg = re.compile(r"""
    < (?: [^n>]+ | \Bn | n(?!ame\s*=) )+   # begining of the tag 
                                           # until the name attribute
    name \s* = \s* ["']?                   # attribute until the value
    ( (?: [^\s\\"']+ | \\{2} | \\. )* )    # value
    [^>]*>                                 # end of the tag
""", re.X | re.I | re.S)

namesGroup = myreg.findall(sourceCode)

然而,使用BS4是一个很好的解决方案。