1

我正在使用一个应用程序来搜索这个我现在无法控制的网站,并且想知道是否有一种方法可以只使用正则表达式来忽略重复匹配。

现在我写这个来获取页面源代码中图像源的匹配

使用它来检索 src

<span> <img id="imgProduct.*? src="/(.*?)" alt="

由此

<span> <img id="imgProduct_1" class="SmPrdImg selected"     
onclick="(some javascript);" src="the_src_I_want1.jpg" alt="woohee"> </span>
<span> <img id="imgProduct_2" class="SmPrdImg selected"     
onclick="(some javascript);" src="the_src_I_want2.jpg" alt="woohee"> </span>
<span> <img id="imgProduct_3" class="SmPrdImg selected"     
onclick="(some javascript);" src="the_src_I_want3.jpg" alt="woohee"> </span>

唯一的问题是,上面列出的完全相同的代码在源代码中重复得更低。有没有办法只使用正则表达式来忽略或删除重复项?

4

2 回答 2

2

你的模式不是很好;它对您当前存在的确切源代码太具体了。正如@Truth 评论的那样,如果情况发生变化,您将打破您的模式。我会推荐更像这样的东西:

<img[^>]*src=['"]([^'"]*)['"]

这将匹配src任何标记内的任何属性的内容<img>,无论您的源代码更改多少。

为了防止使用正则表达式重复,您需要前瞻,这可能非常慢。我不建议为此使用正则表达式。这只是为了表明你可以,如果你不得不这样做。您需要的模式是这样的(我使用 Notepad++ 的正则表达式搜索对此进行了测试,它基于 PCRE 并且比 JavaScript 更强大,但我有理由确定 JavaScript 的正则表达式解析器可以处理这个问题)。

<img[^>]*src=['"]([^'"]*)['"](?!(?:.|\s)*<img[^>]*src=['"]\1['"])

然后,您将获得 each 的最后一个实例的匹配项src

故障

为了说明,以下是该模式的工作原理:

<img[^>]*src=['"]([^'"]*)['"]

这确保出现<img>时我们在标签内src,然后确保我们只匹配引号内的内容(可以是单引号或双引号;因为无论如何我们都没有文件名中的合法字符担心混合引用类型或转义引号)。

(?!
    (?:
        .
    |
        \s
    )*
    <img[^>]*src=['"]\1['"]
)

开始一个否定的(?!前瞻:我们要求在这一点之后不能匹配以下模式。

然后(?:.|\s)*匹配任何字符或任何空格。这是因为 JavaScript.不会匹配换行符,而\s会。大多数情况下,我很懒,不想为任何可能的行尾写出模式,所以我只使用了\s. *当然,这意味着我们可以拥有任意数量的这些。这意味着在文件的其余部分中无法找到以下内容(仍然是否定前瞻的一部分) 。而(?:不是(意味着这个括号不会被反向引用记住。

那一点是<img[^>]*src=['"]\1['"]。这与初始模式非常相似,但我们不是捕获srcwith ([^'"]*),而是引用之前捕获src的 with \1

因此,该模式是说“将没有任何内容src的任何内容与文件其余部分中的任何内容匹配”,这意味着您只能获得每个内容的最后一个实例并且没有重复项。imgimgsrcsrc

顺便说一句,如果您想删除所有出现多次的任何实例,我认为您不img走运。srcJavaScript 不支持lookbehind,而且绝大多数支持的正则表达式引擎无论如何都不允许如此复杂的lookbehind

于 2012-08-20T21:07:28.773 回答
1

我不会太努力地使它们独一无二,只需在与 array_unique 的 preg 匹配之后在 PHP 中执行此操作:

$pattern = '~<span> <img id="imgProduct.*? src="/(.*?)" alt="~is';
$match   = preg_match_all($pattern, $html, $matches);

if ($match)
{
     $matches = array_unique($matches[1]);
}

如果您使用的是 JavaScript,那么您需要使用另一个函数而不是 array_unique,请检查 PHPJS: http ://phpjs.org/functions/array_unique:346

于 2012-08-20T21:25:01.727 回答