1

嘿,我有一个关于正则表达式的相当基本的问题。我只想返回正文标签内(包括)内的文本,我知道以下内容是不正确的,因为它也会匹配开始正文标签之前的所有字符。我想知道你将如何跳过这些?

x = re.match('(.*<body).*?(</body>)', fileString)

谢谢!

4

6 回答 6

9

我不了解 Python,但这里有一个使用Beautiful Soup组合在一起的快速示例,我经常看到推荐用于 Python HTML 解析。

import BeautifulSoup

soup = BeautifulSoup(fileString)

bodyTag = soup.html.body.string

这将(理论上)处理 HTML 的所有复杂性,这对于纯正则表达式的答案来说是非常困难的,因为它不是正则表达式的设计目的。

于 2009-10-25T13:32:09.440 回答
2

<body>...</body>这是一些示例代码,它使用正则表达式来查找标签之间的所有文本。尽管这演示了 python 的 re 模块的一些特性,但请注意,Beautiful Soup模块非常易于使用,如果您打算解析 HTML 或 XML,它是一个更好的工具。(请参阅下面的示例,了解如何使用 BeautifulSoup 解析它。)

#!/usr/bin/env python
import re

# Here we have a string with a multiline <body>...</body>
fileString='''baz<body>foo
baby foo
baby foo
baby foo
</body><body>bar</body>'''

# re.DOTALL tells re that '.' should match any character, including newlines.
x = re.search('(<body>.*?</body>)', fileString, re.DOTALL)
for match in x.groups():
    print(match)
# <body>foo
# baby foo
# baby foo
# baby foo
# </body>

如果您想收集所有匹配项,可以使用 re.findall:

print(re.findall('(<body>.*?</body>)', fileString, re.DOTALL))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']

如果你打算多次使用这个模式,你可以预编译它:

pat=re.compile('(<body>.*?</body>)', re.DOTALL)
print(pat.findall(fileString))
# ['<body>foo\nbaby foo\nbaby foo\nbaby foo\n</body>', '<body>bar</body>']

下面是使用 BeautifulSoup 的方法:

#!/usr/bin/env python
from BeautifulSoup import BeautifulSoup

fileString='''baz<body>foo
baby foo
baby foo
baby foo
</body><body>bar</body>'''
soup = BeautifulSoup(fileString)
print(soup.body)
# <body>foo
# baby foo
# baby foo
# baby foo
# </body>

print(soup.findAll('body'))
# [<body>foo
# baby foo
# baby foo
# baby foo
# </body>, <body>bar</body>]
于 2009-10-25T13:18:43.150 回答
0

您不能使用正则表达式解析 HTML。HTML 不是常规语言。改用像 lxml 这样的 HTML 解析器。

于 2009-10-25T15:50:23.233 回答
-2
 x = re.match('.*(<body>.*?</body>)', fileString)

考虑用于 HTML 解析的 minidom。

于 2009-10-25T13:18:22.853 回答
-2
x = re.search('(<body>.*</body>)', fileString)
x.group(1)

打字比匹配答案少

于 2009-10-25T13:25:40.817 回答
-2

您的 fileString 是否包含多行?在这种情况下,您可能需要指定它或显式跳过这些行:

x = re.match(r"(?:.|\n)*(<body>(?:.|\n)*</body>)", fileString)

或者,更简单地使用 re 模块:

x = re.match(r".*(<body>.*</body>)", fileString, re.DOTALL)

x.groups()[0]如果 x 不是 None,则应包含您的字符串。

于 2009-10-25T13:41:02.997 回答