15

是否有任何库可以获取文本(如 html 文档)和字符串列表(如某些产品的名称),然后在字符串列表中找到一个模式并生成一个正则表达式来提取所有文本(html 文档)中与找到的模式匹配的字符串?

例如,给定以下 html:

<table>
  <tr>
    <td>Product 1</td>
    <td>Product 2</td>
    <td>Product 3</td>
    <td>Product 4</td>
    <td>Product 5</td>
    <td>Product 6</td>
    <td>Product 7</td>
    <td>Product 8</td>
  </tr>
</table>

以及以下字符串列表:

['Product 1', 'Product 2', 'Product 3']

我想要一个可以构建如下正则表达式的函数

'<td>(.*?)</td>'

然后从 html 中提取与正则表达式匹配的所有信息。在这种情况下,输出将是:

['Product 1', 'Product 2', 'Product 3', 'Product 4', 'Product 5', 'Product 6', 'Product 7', 'Product 8']

澄清:

我希望该功能可以查看样本的周围环境,而不是样本本身。因此,例如,如果 html 是:

<tr>
  <td>Word</td>
  <td>More words</td>
  <td>101</td>
  <td>-1-0-1-</td>
</tr>

['Word', 'More words']以及我希望它提取的样本:

['Word', 'More words', '101', '-1-0-1-']
4

6 回答 6

10

您的要求同时非常具体且非常笼统。

我认为除非您编写自己的库,否则您永远不会为您的目的找到任何库。

另一方面,如果您花太多时间编写正则表达式,您可以使用一些 GUI 工具来帮助您构建它们,例如: http ://www.regular-expressions.info/regexmagic.html

但是,如果您只需要从 html 文档中提取数据,则应该考虑使用 html 解析器,它应该会使事情变得容易得多。

我建议beautifulsoup在 python 中解析 html 文档: https ://pypi.python.org/pypi/beautifulsoup4/4.2.1

于 2013-07-21T21:46:04.007 回答
7

我很确定在一般情况下(不迂腐)这个问题的答案是否定的。问题在于,任意文本以及该文本的任意子字符串集并未严格定义单个正则表达式。

正如几个人提到的,一个函数可以简单地.*为每组输入返回。或者它可以为输入字符串返回['desired', 'input', 'strings']正则表达式

'(desired)+|(input)+|(strings)+'

或许多其他琐碎正确但完全无用的结果。

您面临的问题是,为了构建正则表达式,您需要严格定义它。为此,您需要使用与您正在使用的正则表达式语言一样富有表现力的语言来描述所需的表达式......字符串加上子字符串列表是不够的(只需查看 RegexMagic 等工具所需的所有选项在有限的环境中计算正则表达式!)。实际上,这意味着您需要所需的正则表达式才能有效地计算它。


当然,您总是可以走百万猴子路线并尝试以某种方式发展适当的正则表达式,但您仍然会遇到需要大量文本样本输入 + 预期输出以获得可行表达式的问题。另外,它需要很长时间才能运行,并且从周日开始可能会因为无用的碎屑而变得臃肿六种。你自己写可能会更好。

于 2013-07-24T16:54:38.010 回答
4

I had a similar problem. Pyparsing is a great tool to do exactly as you said.

https://github.com/pyparsing/pyparsing

It allows you to build expressions much list a regex but much more flexible. The site has some good examples.

Here is a quick script for the problem you posed above:

from pyparsing import *
cell_contents = []
results = []
text_string="""<table>
<tr>
     <td>Product 1</td>
     <td>Product 2</td>
     <td>Product 3</td>
     <td>Product 4</td>
     <td>Product 5</td>
     <td>Product 6</td>
     <td>Product 7</td>
     <td>Product 8</td>
</tr>
</table>"""

text_string = text_string.splitlines()
for line in text_string:
    anchorStart,anchorEnd = makeHTMLTags("td")
    table_cell = anchorStart + SkipTo(anchorEnd).setResultsName("contents") + anchorEnd
    for tokens,start,end in table_cell.scanString(line):
        cell_contents = ''.join(tokens.contents)
        results.append(cell_contents)

for i in results:
    print i
于 2013-07-24T00:01:48.627 回答
2

尝试这个:

https://github.com/noprompt/frak

它是用 Clojure 编写的,不能保证它输出的是最简洁的表达式,但似乎有一些潜力

于 2013-11-25T23:01:20.183 回答
0

也许最好使用支持 XPATH 的 Python HTML 解析器(请参阅此相关问题),在 HTML 代码中查找感兴趣的部分,然后记录它们的 XPATH——或者至少是由多个共享路径共享的 XPATH。例子?

于 2013-07-22T09:02:04.583 回答
-2

与其生成正则表达式,不如使用更通用的正则表达式?如果你的数据被限制在一个本身不包含元素的元素的内部文本中,那么这个与 re.findall 一起使用的正则表达式将产生一个元组列表,其中每个元组都是(标记名,文本):

r'<(?P<tag>[^>]*)>([^<>]+?)</(?P=tag)>'

然后,您可以轻松地从每个元组中提取文本。

于 2013-07-21T20:42:44.237 回答