1

我正在尝试创建一个用于报废的正则表达式生成器,任何指导都值得赞赏。

我们的想法是,我们有一个大文本 (html),我们选择 2 个(至少)始终相似的 DOM 元素(例如来自 google 的前 2 个结果),然后我们应该生成一个正则表达式来抓取(匹配)这个结果。

示例:选定元素 1(这将由用户输入):

<a onmousedown="return rwt(this,'','','','1','AFQjCNHqQo9TrXtXXM5lDpiCmNQO9xwkhw','','0CGoQFjAA',null,event)" class="l" href="http://www.miniclip.com/"><em>Games</em> at Miniclip.com - Play Free Online <em>Games</em></a>

选定的元素 2(这将由用户输入):

<a onmousedown="return rwt(this,'','','','2','AFQjCNGlNySkvcXMxEUmjCMOJRQPCdqBHQ','','0CHIQFjAB',null,event)" class="l" href="http://www.games.com/"><em>Games</em>.com: Play <em>Games</em> Online - Free <em>Games</em>, Download <em>Games</em> <b>...</b></a>

包含这两个元素的 HTML 文本:

<ol id="rso" eid="GcrGT_KHH4f3sgbXmci5Cw"><!--m--><li class="g"><div sig="U8P" bved="0CBUQkQo" pved="0CBQQkgowAA" class="vsc"><h3 class="r"><a onmousedown="return rwt(this,'','','','1','AFQjCNHqQo9TrXtXXM5lDpiCmNQO9xwkhw','','0CGoQFjAA',null,event)" class="l" href="http://www.miniclip.com/"><em>Games</em> at Miniclip.com - Play Free Online <em>Games</em></a></h3><div class="vspib" aria-label="Detalii rezultat" role="button" tabindex="0">

</div></div></div><!--n--></li><!--m--><li class="g"><div sig="fUe" bved="0CBsQkQo" pved="0CBoQkgowAQ" class="vsc"><h3 class="r"><a onmousedown="return rwt(this,'','','','2','AFQjCNGlNySkvcXMxEUmjCMOJRQPCdqBHQ','','0CHIQFjAB',null,event)" class="l" href="http://www.games.com/"><em>Games</em>.com: Play <em>Games</em> Online - Free <em>Games</em>, Download <em>Games</em> <b>...</b></a></h3><div class="vspib" aria-label="Detalii rezultat" role="button" tabindex="0">

在这种情况下,好的正则表达式是:

(<h3 class="r">)(.*?)(</h3><div)

不难弄清楚。当<h3 class="r">出现在与我们的结果无关的另一个元素中时,就会出现问题。例如,如果您添加:

<h3 class="r">THIS IS JUST AN EXTRA THING</h3> 

在 HTML 文本的开头,上面的正则表达式不起作用。

新的正则表达式需要:

(class="vsc"><h3 class="r">)(.*?)(</h3><div)

我知道这不是一件容易实现的事情,但我的想法是找到元素的相似之处(例如,在元素前后取 100 个字符,看看元素 1/元素 2 的相同点)。

希望有人可以指导我实现这一目标的最佳方法。

提前致谢

4

1 回答 1

0

如果我正确理解了这个问题,那么您需要的第一件事是返回一个正则表达式,该表达式最适合特定字符串,给定该字符串(和一些上下文)。似乎有一些选择,包括Regulazytxt2re

您需要的下一件事情是遍历 DOM 的能力,因为您正在寻找父级(例如,在您的示例中给出了 2 个链接,您想要找到周围的 h3)。您可以尝试通过正则表达式执行此操作,但这会很困难,并且您可能无法正确处理所有边缘情况。有各种工具可用于修复不符合 XML 的 HTML 和遍历生成的 DOM,例如我前几天在 Java 中使用NekoHTML进行此操作。

此时,您可以应用如下算法:

  1. 找到两个给定节点之间的第一个公共父节点。
  2. 从父级的文本内容构建正则表达式。
  3. 将正则表达式应用于顶级 html 节点的内容。
  4. 如果您获得超过 1 个匹配项(双 h3 案例),则缩小到父级的父级。
  5. 冲洗并重复,从第 2 步开始,使用新的父母。

秘诀显然在于如何从字符串生成正则表达式,但听起来你可以依靠一些第三方工具来完成这部分。本质上,您正在做的是为正则表达式编译器创建一个字符串,因此,如果您需要从头开始实现这一点,一种方法可能是对字符串进行标记并构建一个Abstract Syntax Tree。然后,您可以访问AST 节点以运行优化(例如查找可以用正则表达式 */+ 运算符替换的重复连续节点),然后在最后一次访问中生成正则表达式。

在更高的层次上,您可能想考虑正则表达式是否真的是您问题的正确答案。如果您只是想在 Google 上查找链接,给出几个示例,您可能只需遍历 DOM 以查找父节点,然后获取所有链接的子节点。

于 2012-06-26T21:51:47.907 回答