Python库生成正则表达式

时间:2013-07-19 15:33:08

标签: python regex

是否有任何lib可以获取文本(如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-']

6 个答案:

答案 0 :(得分:10)

您的要求同时非常具体且非常一般。

除非你自己编写,否则我认为你找不到任何图书馆。

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

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

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

答案 1 :(得分:6)

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

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

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

或者其他很多其他非常正确但完全没用的结果。

您面临的问题是,为了构建正则表达式,您需要严格定义它。要做到这一点,你需要使用语言描述所需的表达式,就像你正在使用的正则表达式语言一样......字符串加上一个子串列表是不够的(只需查看RegexMagic需要的工具的所有选项)在有限的环境中计算正则表达式!)。实际上,这意味着您需要所需的正则表达式,以便有效地计算它。


当然,您可以随时使用百万只猴子路线并尝试以某种方式进化一个合适的正则表达式,但您仍然会遇到需要大量文本输入的问题+预期产出以获得可行的表达。此外,它还需要很长时间才能运行,并且可能会在星期天以无用的碎屑六种方式臃肿。你可能最好自己写一下。

答案 2 :(得分:2)

我有类似的问题。 Pyparsing是一个很好的工具,就像你说的那样。

https://github.com/pyparsing/pyparsing

它允许你构建表达式列表正则表达式,但更灵活。该网站有一些很好的例子。

以下是您在上面提出的问题的快速脚本:

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

答案 3 :(得分:2)

试试这个:

https://github.com/noprompt/frak

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

答案 4 :(得分:0)

也许最好使用支持XPATH的Python HTML解析器(参见this related question),在HTML代码中查找感兴趣的内容,然后记录他们的XPATH - 或至少记录他们共享的内容。不止一个例子?

答案 5 :(得分:-2)

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

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

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