【问题标题】:content URLs regexp内容 URL 正则表达式
【发布时间】:2009-11-25 01:28:27
【问题描述】:

我从 db 收到一段代码,其中偶尔包含 url,例如,http://site.tld/lorem.ipsum/whatever 现在我想用一个辅助方法把它变成用户可以点击的漂亮链接。如:

<a href="http://site.tld/lorem.ipsum/whatever">http://site.tld/lorem.ipsum/whatever</a>

当然,任何人都可以做到这一点,[^\s]+ 可以做到这一点。但明显的问题是,如果我有一个点 (.),例如,在 URL 之后,我不希望它包含在链接中。因此,我们需要将 URL 限制为多个字符,但我们不能创建一个规则来匹配不是特定字符的字符,因为我之前提到的点是“url stopper”,但它也可以是包含在 URL 中。 我的第一个猜测是:

(http\:\/\/[^\s]+)(\,|\.|\;|\:)?

将被替换为

<a href="$1">$1</a>$2

但它不起作用,因为第二个变量容器是可选的,最好将这些字符包含在第一个容器中,因为除了空格字符之外,任何内容都可以。

非常感谢您的帮助,但老实说,我不希望在互联网上找到目前似乎有效的巨大规则。我敢肯定有一个很酷的方法来获得这个。我对正则表达式有一个不错的理解,但是这种情况似乎是我以前没有经历过的。或者也许我错过了什么,毕竟已经过了凌晨 3 点。

谢谢!

编辑:

@Chirael 为我清除它,但这是我的最终解决方案:

(http\:\/\/[^\s]+?)(\,|\.|\;|\:)?(\s|$)
  1. 我正在清除斜线,因为我使用的是 PHP
  2. 我在第二个变量中添加了更多字符作为“URL 停止符”
  3. 由于第一个变量变为“非贪婪”,并且第二个是可选的,如果未指定第三个,则链接将仅包含“http://”之后的第一个字符。但是当 URL 是文本中的最后一件事时出现了问题,因此现在第三个变量可以是空格字符或文本的结尾。

【问题讨论】:

    标签: regex url


    【解决方案1】:

    打滑,添加一个?在 [^\s]+ 之后使其不贪婪,然后是“可选”句点 ? - 我在文件中使用了以下示例文本:

    Lorem I receive a block of code from db which occasionally contains
    urls, e.g, http://site.tld/lorem.ipsum/whatever and
    http://site.tld/lorem.ipsum/whatevertwo. Now I want to turn this into
    nice clickable link for the user, with a helper method. Such as.
    

    然后在命令行上运行如下代码,似乎满足你的要求:

    perl -pe 's#(http://[^\s]+?)(\.?)(\s)#<a href="$1">$1</a>$2$3#g' foo.txt
    

    ...导致:

    Lorem I receive a block of code from db which occasionally contains
    urls, e.g, <a href="http://site.tld/lorem.ipsum/whatever">http://site.tld/lorem.ipsum/whatever</a> and
    <a href="http://site.tld/lorem.ipsum/whatevertwo">http://site.tld/lorem.ipsum/whatevertwo</a>. Now I want to turn this into
    nice clickable link for the user, with a helper method. Such as.
    

    这行得通吗?

    【讨论】:

    • 太棒了!我知道一定有这种概念。当你说“让它不贪婪”时,我的心就长大了。这正是我想要的。我记得我以前用过这个,但现在我想我的灵感减少了。你知道我在哪里可以找到关于这个想法的东西,以确保我 100% 了解它是如何工作的吗?再次感谢!
    • 太棒了 - 如果这回答了您的问题,您介意单击复选标记“接受”吗?我是该网站的新手,已经被整个“声誉评分”所吸引;)(谢谢:)
    • 哦,至于贪婪或非贪婪的概念,我手头没有规范的资料,因为我在 1990 年代中期了解正则表达式,当时 Perl 是语言,CGI 是要做的事情(回到 Perl 4 的鼎盛时期)。所以我唯一可以推荐的是“man perlre”,尽管我相信 O'reilly 有一本关于正则表达式的书可能值得一读。
    • 嘿,谢谢。看看我的最后笔记,我把它包起来了,它现在非常适合我的需要。
    【解决方案2】:

    您也可以尝试不同的方法:您可以指定可接受的最后一个字符,而不是列出您希望包含在 URL 末尾的内容。在这个例子中:

    $str = preg_replace('#(http://\S+[a-z0-9/])#', '<a href="\1">\1</a>', $str);
    

    我要求在末尾输入一系列非空格和一个字母数字字符(加斜线)(这通常是有效 URL 的结束方式)。

    还有一些注意事项:

    • 在 PHP(如 Perl)中,您可以选择模式分隔符,/ / 只是常规的,但您可以(几乎)选择您喜欢的任何字符:选择正确的分隔符可以避免大量转义
    • 单个字符的交替最好写成一个字符类:[,.;:](\,|\.|\;|\:) 更容易阅读,(\,|\.|\;|\:) 还包括不必要的转义(只有点需要它)
    • 了解哪些需要转义,哪些不需要转义,用反斜杠填充模式会使其不可读

    【讨论】:

    • 当我有更多时间时,我将不得不修改这个,但你的方法似乎很完美,但它似乎如此明显,以至于我不敢相信它没有出现在我的脑海中。另外,关于模式分隔符,我该如何选择它?只是将其写为第一个字符会自动将其分配为分隔符?我想我从来没有掌握过何时使用方括号(除了需要变量容器或特定字符类,如 a-z、0-9 等)以及使用哪种类型。转义是对的,它看起来很难看,但我注意到它有时取决于语言,所以我的想法很安全。谢谢!
    • 是的,模式中的第一个字符成为分隔符,你必须在最后匹配它。您还可以使用各种括号,在这种情况下,您可以“自然地”匹配它们,而不是重复第一个字符:(..pattern..){..pattern..} 等等。
    【解决方案3】:

    你可以试试这个:

    正则表达式:

    (http?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?)
    

    替换:

    <a href="$1">$1</a>
    

    【讨论】:

    • 谢谢。我正在使用 PHP,其中规则是用斜杠包装的,例如:'/(.*)/'。因此,您的规则当前会触发错误(未知修饰符“/”)。我尝试从规则中转义所有包含的斜线,但结果就像我的一样,点包含在 URL 中。但是,它正确地从其中一个 URL 中排除了逗号。
    • 你就在那里打滑,“-”字符也可能违反此规则。
    猜你喜欢
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多