【问题标题】:Regular expression to find URLs not inside a hyperlink用于查找不在超链接内的 URL 的正则表达式
【发布时间】:2023-03-08 17:42:01
【问题描述】:

有很多正则表达式可以匹配 URL。但是,我正在尝试匹配未出现在<a> 超链接标记(HREF、内部值等)中任何位置的 URL。所以这些中的所有 URL 都不应该匹配:

某事 http://www.example2.com 某事http://www.example.com/测试

<a></a> 之外的任何 URL 都应匹配。

我尝试的一种方法是使用否定前瞻来查看 URL 之后的第一个 <a> 标记是打开 <a> 还是关闭 </a>。如果它是关闭的</a>,则 URL 必须在超链接内。我认为这个想法没问题,但是负前瞻正则表达式不起作用(或者更准确地说,正则表达式没有正确编写)。非常感谢任何提示。

【问题讨论】:

标签: html regex url


【解决方案1】:

我也在寻找这个答案,因为那里没有像我想要的那样真正有效,这是我创建的正则表达式。显然,由于它是一个正则表达式,请注意这不是一个完美的解决方案。

/(?!<a[^>]*>[^<])(((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?))(?![^<]*<\/a>)/gi

更新html的整个函数是:

function linkifyWithRegex(input) {
  let html = input;
  let regx = /(?!<a[^>]*>[^<])(((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?))(?![^<]*<\/a>)/gi;
  html = html.replace(
    regx,
    function (match) {
      return '<a href="' + match + '">' + match + "</a>";
    }
  );
  return html;
}

【讨论】:

    【解决方案2】:

    您可以分两步完成,而不是试图想出一个正则表达式:

    1. 混合(替换为空)HTML 锚部分(整个锚标记:开始标记、内容和结束标记)。

    2. 匹配网址

    在 Perl 中可能是:

    my $curLine = $_; #Do not change $_ if it is needed for something else.
    $curLine =~ /<a[^<]+<\/a>//g; #Remove all of HTML anchor tag, "<a", "</a>" and everything in between.
    if ( $curLine =~ /http:\/\//)
    {
      print "Matched an URL outside a HTML anchor !: $_\n";
    }
    

    【讨论】:

    • 如果我删除(混合)HTML 锚点,我将无法确定 URL 最初是否在超链接中,对吗?我只是在寻找超链接标签之外的 URL。
    • 我的意思是:从开始锚标记中删除 everything 直到结束锚标记。
    • 啊,很好的解决方案。我让它工作了。起初我以为你只是要删除开始和结束标签,但删除整个标签是诀窍。谢谢!!
    • -1 您应该通过适当的解析器删除 元素,因为 HTML 不是常规语言。
    • @Svante:我认为这不公平。不应该直接针对这个问题吗?问题是关于匹配正则表达式。
    【解决方案3】:

    您可以使用匹配锚标记和超链接的单个正则表达式来做到这一点:

    # Note that this is a dummy, you'll need a more sophisticated URL regex
    regex = '(<a[^>]+>)|(http://.*)'
    

    然后循环遍历结果,只处理找到第二个子模式的匹配项。

    【讨论】:

    • @Svante:首先,您可以轻松扩展示例以匹配 和 中的所有内容。然后它与接受的答案相同,只是一次通过。其次,不,“it”不会尝试解析任何内容,而是基于 HTML ish 字符串的出现来解析常规语言。如果您只想在字符串中找到简单的模式,则无需使用功能齐全的 HTML 解析器。
    【解决方案4】:

    彼得有一个很好的答案:首先,移除锚点,以便

    Some text <a href="http://page.net">TeXt</a> and some more text with link http://a.net
    

    被替换为

    Some text  and some more text with link http://a.net
    

    然后运行一个查找 url 的正则表达式:

    http://a.net
    

    【讨论】:

      【解决方案5】:

      使用 DOM 过滤掉锚元素,然后对其余部分执行简单的 URL 正则表达式。

      【讨论】:

        【解决方案6】:
         ^.*<(a|A){1,1}  ->scan until >a or >A is found
         .*(href|HREF){1,1}\=  -> scan until href= or HREF=
          \x22{1,1}.*\x22  -> accept all characters between two quotes
          > -> look for >
          .+(|){1,1} -> accept description and end anchor tag
          $ -> End of string search
        
        
            pattern= "^.*<(a|A){1,1}.*(href|HREF){1,1}.*\=.*\x22{0,1}.*\x22{0,1}.*>.+(|){1,1}$"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-23
          • 2013-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多