regex 用于生成正则表达式的Python库

2o7dmzc5  于 2023-01-03  发布在  Python
关注(0)|答案(7)|浏览(115)

有没有什么库可以接受一个文本(比如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-']
sqougxex

sqougxex1#

你的要求同时是非常具体和非常一般的。
我不认为你会找到任何库为您的目的,除非你写自己的。
另一方面,如果你花了太多时间编写正则表达式,你可以使用一些GUI工具来帮助你构建它们,比如:http://www.regular-expressions.info/regexmagic.html

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

我推荐使用beautifulsoup来解析python中的html文档:https://pypi.python.org/pypi/beautifulsoup4/4.2.1

idfiyjo8

idfiyjo82#

我非常肯定这个问题的答案在一般情况下(不是学究气)是no.问题是一个任意的文本,以及该文本的任意子字符串集,没有严格地定义一个正则表达式。
就像一些人提到的,一个函数可以简单地为每一组输入返回.*,或者它可以为输入字符串['desired', 'input', 'strings']返回regex

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

或者大量其他平凡正确但完全无用的结果。
你所面临的问题是,为了构建一个正则表达式,你需要严格地定义它。要做到这一点,你需要使用像你所使用的正则表达式语言一样具有表达力的语言来描述所需的表达式......一个字符串加上一系列子字符串是不够的(只要看看像RegexMagic这样的工具在有限的环境中计算正则表达式所需的所有选项就可以了!)。这意味着你需要你想要的正则表达式,以便有效地计算它。
当然,你总是可以走百万只猴子的路线,试图以某种方式“进化”出一个合适的正则表达式,但是你仍然会遇到这样的问题:为了得到一个可行的表达式,你需要大量的文本样本输入+预期输出。另外,它会花费很长时间来运行,而且可能从星期天开始就被无用的碎片膨胀了六次。你最好自己写它。

ljo96ir5

ljo96ir53#

我也遇到过类似的问题。pyparser是一个很好的工具,可以完全按照你说的做。
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
voj3qocg

voj3qocg4#

试试这个:
https://github.com/noprompt/frak
它是用Clojure编写的,不能保证它输出的是最简洁的表达式,但似乎有一些潜力

nzrxty8p

nzrxty8p5#

也许使用支持XPATH的Python HTML解析器会更好(参见this related question),在HTML代码中查找感兴趣的部分,然后记录它们的XPATH--或者至少记录由多个示例共享的XPATH。

hpcdzsge

hpcdzsge6#

const table = document.querySelector("table");
const rows = table.querySelectorAll("tr");

let array = [];

for (const row of rows) {
  const cells = row.querySelectorAll("td");
  let rowArray = [];
  for (const cell of cells) {
    rowArray.push(cell.textContent);
  }
  array.push(rowArray);
}

console.log(array);
jhiyze9q

jhiyze9q7#

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

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

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

相关问题