5

我正在使用正则表达式来查找任何 URL 并相应地链接它们。但是,我不想链接任何已经链接的 URL,所以我使用后向查看 URL 之前是否有 href。但是这失败了,因为在 PHP 的前瞻和后瞻中不允许使用可变长度量词。

这是比赛的正则表达式:

/\b(?<!href\s*=\s*[\'\"])((?:http:\/\/|www\.)\S*?)(?=\s|$)/i

解决这个问题的最佳方法是什么?

编辑:

我还没有对其进行测试,但我认为在单个正则表达式中执行此操作的诀窍是在正则表达式中使用条件表达式,这由 PCRE 支持。它看起来像这样:

/(href\s*=\s*[\'\"])?(?(1)^|)((?:http:\/\/|www\.)\w[\w\d\.\/]*)(?=\s|$)/i

关键是如果href被抓到了,由于有条件的,会立即抛出匹配(?(1)^|),保证不匹配。它可能有什么问题。我明天测试一下。

4

3 回答 3

2

我尝试反过来做同样的事情:确保 URL 不以">:

/((?:http:\/\/|www\.)(?:[^"\s]|"[^>]|(*FAIL))*?)(?=\s|$)/i

但对我来说,这看起来很老套,我相信你可以做得更好。

我的第二种方法与您的更相似(因此更精确):

/href\s*=\s*"[^"]*"(*SKIP)(*FAIL)|((?:http:\/\/|www\.)\S*?)(?=\s|$)/i

如果我找到一个href=I (*SKIP)(*FAIL)。这意味着当遇到(*SKIP).

但这同样是骇人听闻的,我相信还有更好的选择。

于 2010-10-15T09:24:52.087 回答
0

我没有更好的正则表达式。但如果你没有找到更好的正则表达式,那么我建议对任务使用两个查询。首先,找到并删除所有链接,然后搜索 url。这可能会更容易和更快。(对于一次查找和替换,您可以使用类似 - http://www.satya-weblog.com/2010/08/php-regex-find-and-replace-any-word-string-or- text-at-one-go.html )。

于 2010-10-15T15:46:13.330 回答
0

找到“不属于链接的每个 URL”是非常困难的否定逻辑。找到每个 URL,然后是作为链接的每个 URL,然后从前一个列表中删除每个 URL,可能会更容易。

至于查找哪些 URL链接的一部分,请尝试:

/<a([\s]+[\w="]+)*[\s]+href[\s]*=[\s]*"([\w\s:/.?+&=]+)"([\s]+[\w="]+)*>/i

我用http://regexpal.com/对其进行了测试以确保。它查找第<a一个,然后它允许任何数量的参数,然后是href,然后是任何其他数量的参数。如果没有href,则不是链接。如果它不是<a>标签,则它不是链接。由于这只是我们要从其他(URL)列表中删除的列表,我将 URL 的定义简化为[\w\s:/.?+&=]+. 就生成 URL 列表而言,您需要更智能的东西。

于 2010-10-15T15:54:46.337 回答