【问题标题】:Enhancing regex to match more URLs增强正则表达式以匹配更多 URL
【发布时间】:2016-02-18 06:32:22
【问题描述】:

考虑这个正则表达式:

  static String AdrPattern="(?:http://www\\.([^/&]+)\\.com/|(?!^)\\G)/?([^/]+)";

我有两个小问题:

  1. 如何使它匹配只有 域名,没有任何进一步的路径/段? (如 https://stackoverflow.com)
  2. 如何使此正则表达式匹配具有不同域扩展名的 URL?

P.S:正则表达式取自 here 并且工作正常,但这两个缺点应该得到修复。

编辑

根据下面的代码,对这篇文章的回答将跳过进一步的部分,只打印域名

         static String AdrPattern= "(?:(?!\\A)\\G(?:/([^\\s/]+))|http://www\\.([^\\s/&]+)\\.(?:com|net|gov|org)(?:/([^\\s/]+))?)";
         static Pattern WebUrlPattern = Pattern.compile (AdrPattern);
         WebUrlMatcher= WebUrlPattern.matcher(line);



        int cn=0;
        while(WebUrlMatcher.find()) {

    if (cnt == 0) 
        {
           String extractedPath = WebUrlMatcher.group(1);

           if(extractedPath!=null){

            fop.write(prefix.toLowerCase().getBytes());


            fop.write(System.getProperty("line.separator").getBytes());



            }

  if(extractedPath!=null)
  {
                fop.write(extractedPath.toLowerCase().getBytes());

                fop.write(System.getProperty("line.separator").getBytes());
  }        

       String extractedPart = WebUrlMatcher.group(2);
       String extractedPart = WebUrlMatcher.group(2);
   String extracted2=WebUrlMatcher.group(3);
   if(extractedPart!=null)
   {
            fop.write(extractedPart.toLowerCase().getBytes());       
            fop.write(System.getProperty("line.separator").getBytes());

            if(extracted2!=null)
            {
            fop.write(extracted2.toLowerCase().getBytes());
            fop.write(System.getProperty("line.separator").getBytes());
            }

   cnt = cnt + 1;

   }
}
    }

    }

【问题讨论】:

  • 你能提供应该和不应该匹配的 URL 示例吗?
  • @TimBiegeleisen 总之,我想要所有的 URL 匹配,但我也想要,对于那些有更多路径/段的,它分别返回它们。换句话说,我想访问这些细分市场。结果,生成了该正则表达式,但它跳过了具有单个路径的 URL,如所示示例。此外,它一次仅适用于单个域扩展。如果可能,我想要这两个修复?
  • 这不是一个词,它是一个段落,它仍然让我不确定你到底想要什么。在 Stack Overflow 上,一张图片值一千字。
  • 所以你希望它在可用时同时匹配域 段?
  • @sln 完全正确。但这个正则表达式没有。此外,它一次应该不止匹配一个域扩展。

标签: java regex url


【解决方案1】:

这是一种方法。对当前正则表达式的轻微操作。
只需测试捕获组。

 "(?:(?!\\A)\\G(?:/([^\\s/]+))|http://www\\.([^\\s/&]+)\\.(?:com|net)(?:/([^\\s/]+))?)"

 (?:
      (?! \A )                      # Not BOS
      \G                            # Start from last match
      (?:
           /  
           ( [^\s/]+ )                   # (1), Required Next Segment path (or fail)
      )
   |                              # or,
      http://www\.                  # New match
      ( [^\s/&]+ )                  # (2), Domain
      \.
      (?: com | net )               # Extension
      (?:
           /  
           ( [^\s/]+ )                   # (3), Optional First Segment path
      )?
 )

测试捕获的 -

输入:

http://www.asfdasdf.net/  
http://www.asfdasdf.net/first  
http://www.asfdasdf.net/first/second  

输出:

 **  Grp 0 -  ( pos 0 , len 23 ) 
http://www.asfdasdf.net  
 **  Grp 1 -  NULL 
 **  Grp 2 -  ( pos 11 , len 8 ) 
asfdasdf  
 **  Grp 3 -  NULL 

-------------

 **  Grp 0 -  ( pos 28 , len 29 ) 
http://www.asfdasdf.net/first  
 **  Grp 1 -  NULL 
 **  Grp 2 -  ( pos 39 , len 8 ) 
asfdasdf  
 **  Grp 3 -  ( pos 52 , len 5 ) 
first  

-------------

 **  Grp 0 -  ( pos 61 , len 29 ) 
http://www.asfdasdf.net/first  
 **  Grp 1 -  NULL 
 **  Grp 2 -  ( pos 72 , len 8 ) 
asfdasdf  
 **  Grp 3 -  ( pos 85 , len 5 ) 
first  

-------------

 **  Grp 0 -  ( pos 90 , len 7 ) 
/second  
 **  Grp 1 -  ( pos 91 , len 6 ) 
second  
 **  Grp 2 -  NULL 
 **  Grp 3 -  NULL 

【讨论】:

  • 这不起作用。它返回 NULL。对于像 http://www.meddybemps.com/ (the first URL in the list) 这样的 URL
  • 或者我做错了?我使用与in here 解释的相同方法来访问组。也应该改吗?
  • @lonesome - 更新了捕获的示例输入/输出。是的,他们变了。组 1 是下一个路径段的延续。第 2 组是一个新域(第 3 组将是第一个路径段,是可选的)。
  • 没有没有。你误会我了。我的意思是,我怎样才能访问这些零件?我使用了链接中显示的旧方法,但它返回 NULL。
  • 对捕获组的访问是相同的。用于 null 的 test 是不同的。 (参见上面的输出)。如果匹配,则使用如果组 2 不是 NULL(有一个域)然后检查组 3 是否不是 NULL(有第一个段)。否则,如果组 1 不为 NULL,则有一个 next 路径段,等等 ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2015-09-14
  • 2021-12-31
  • 2016-12-12
相关资源
最近更新 更多