1

根据 Expresso 的说法,我正在尝试为Woofy编写一个脚本(tl;dr 是一个下载网络漫画的程序),但显然我的正则表达式无法找到上一页的链接。我试图找到一些类似的东西:

<a href="http://70-seas.com/?p=1253" title="Prologue 01" class="previous-comic-link"><span>&lsaquo; Previous</span></a>

每个页面都不同,URL 和标题会更改为链接到上一页的任何内容,其中:

<a\shref="http://70-seas.com/?p=[0-9]{4}"\stitle="[.]*\s[.]*\s([.]*)?"\sclass="previous-comic-link"><span>&lsaquo;\sPrevious</span></a>

(有时标题有三个词,有时有两个词。不过,它们总是以数字作为最后一个词。)

鉴于我之前没有任何正则表达式的经验或正式培训,我不知道我做错了什么。任何帮助,将不胜感激。

4

1 回答 1

0

有几件事需要解决。

首先,看一下http://70-seas.com/?p=[0-9]{4}部分。这里/?的意思是/字符是可选的。要匹配您要匹配文字?字符的 URL。由于该?字符是一个正则表达式元字符,这使得某些东西是可选的,因此您需要对其进行转义以使其与字面匹配。为此,请使用\?. 因此,更新的部分变为http://70-seas.com/\?p=[0-9]{4}。您还添加了expresso标签,因此您可以遍历模式树并发现此问题。

接下来,真正的问题在于这部分:title="[.]*\s[.]*\s([.]*)?". 正则表达式中的方括号表示匹配其中任何字符的字符类。真正的[.]意思是“匹配'。字符”这不是你的意图。您可能想使用.匹配任何字符的元字符,但最终通过将其放在字符类中来匹配它。接下来,您将第三部分设为可选,而您可能打算将\s最后一个可选组包含在内。考虑到这些要点,您应该使用:title=".*\s.*(\s.*)?".

那应该行得通。但是,它不是最好的正则表达式,并且使用.*通常对我来说是一个危险信号。.匹配任何字符,这是一种贪婪的模式,可能会超出预期的消耗。最好尝试具体。如果要匹配字母数字字符,请\w改用。根据您的描述,您需要 1-3 个字。这可以表示为\w+(?:\s\w+){0,2}。更干净,更容易理解。它表示我们正在匹配一个或多个字母数字字符,然后是一个非捕获组,(?:\s\w+)这意味着匹配一个空格,然后是一个或多个字母数字字符。最后,我们将{0,2}量词放在组的末尾,表示我们要匹配这个组 0-2 次。这(?:...)如果您不需要捕获,语法会使组不捕获,从而提高性能。

您还应该做的一件事是转义所有双引号。它可能会或可能不会有所不同,具体取决于您使用的内容,但它通常是需要的。所以你的双引号会变成\".

你现在应该有这样的模式:

<a\shref=\"http://70-seas.com/\?p=[0-9]{4}\"\stitle=\"\w+(?:\s\w+){0,2}\"\sclass=\"previous-comic-link\"><span>&lsaquo;\sPrevious</span></a>

这很好,但这可能更简单。每当您必须匹配双引号之间的某些内容时,只要您不需要匹配其中的任何项目以供以后参考,那么您可以使用title=\"[^"]+\". 该[^"]+部分使用负字符类,由^字符类开头的字符表示。它基本上匹配任何不是双引号的字符。一旦遇到标题末尾的双引号,匹配将终止。无需担心 1-3 个单词,因为您只想匹配标题的全部内容。

新模式变为:

<a\shref=\"http://70-seas.com/\?p=[0-9]{4}\"\stitle=\"[^"]+\"\sclass=\"previous-comic-link\"><span>&lsaquo;\sPrevious</span></a>
于 2013-11-13T16:43:02.110 回答