首页 新闻 会员 周边 捐助

正则表达式匹配内容中相同Domain的Url 的数量

0
悬赏园豆:50 [已解决问题] 解决于 2018-02-07 17:01

下面是一个待匹配的内容:

http://q.cnblogs.com/test
q.cnblogs.com
cnblogs.com
www.baidu.com
www.sina.com
www.google.com

我想要匹配到的是同个Domain的Url 数量,当然上述的只是一个例子,Domain 不固定。
比如上面我想得到的Url数量为3

问题补充:

我需要不是仅仅匹配Url地址的,我需要的是匹配同一个Domain的

BUTTERAPPLE的主页 BUTTERAPPLE | 老鸟四级 | 园豆:3190
提问于:2018-02-06 10:42

这个样本有些问题,如果出现 asp.net 算不算域名,如果是 url 的,总得有个路径,比如 q.cnblogs.com/

dudu 6年前

@dudu: 这个 / 很关键,解决了我很多困惑。

BUTTERAPPLE 6年前
< >
分享
最佳答案
1

稍微修改一下样本,给域名之后加上斜杠,我想到的基于.net core的一种实现方式:

class Program
{
    static void Main(string[] args)
    {
        var text = @"http://q.cnblogs.com/test
q.cnblogs.com/
cnblogs.com/
www.baidu.com/
www.sina.com/
www.google.com/";

        var regex = new Regex(@"(?:[a-za-z0-9-]{1-50}[..])?([a-za-z0-9-]{1,20}[..][a-za-z]{2,4}(?:[..][a-za-z]{2})?)/");
        var matches = regex.Matches(text);            
        var domains = matches.Select(m => m.Groups[1].Value);

        var result = domains.GroupBy(x => x)
            .Select(x => new { Domain = x.Key, Count = x.Count() })
            .OrderByDescending(x => x.Count)
            .FirstOrDefault();

        Console.WriteLine($"{result.Domain}, {result.Count}");
        //Output is cnblogs.com, 3
    }
}

注:a-z是为了匹配全角英文

收获园豆:30
dudu | 高人七级 |园豆:30948 | 2018-02-07 14:56

获取domain时,需要进行Cast 转换:

 var domains = matches.Cast<Match>().Select(m => m.Groups[1].Value);

PS: 这方法可比我存到 HashSet 里面简单许多。

BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-07 16:40

@BUTTERAPPLE: 我这里测试不需要Cast,MatchCollection 实现了 IEnumerable<Match> 接口

dudu | 园豆:30948 (高人七级) | 2018-02-07 17:35

@dudu: 新建了一个项目确实是不用Cast的,在现有项目中就死活下面这样:

'MatchCollection' does not contain a definition for 'Select' and no extension method 'Select' accepting a first argument of type 'MatchCollection' could be found 
BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-07 18:06

@dudu: 我知道了,使用netcoreapp2.0 是没问题的,使用netstandard2.0就需要转换

BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-07 18:16

@BUTTERAPPLE: 果然它们的MatchCollection实现不一样
netstandard2.0:

public class MatchCollection : ICollection, IEnumerable
{ }

netcoreapp2.0:

public class MatchCollection : ICollection, IEnumerable, ICollection<Match>, IEnumerable<Match>, IList<Match>, IReadOnlyCollection<Match>, IReadOnlyList<Match>, IList
{ }
dudu | 园豆:30948 (高人七级) | 2018-02-07 18:28

代码中需要判断匹配数为0的会出现的Object null 错误。

BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-10 15:56
其他回答(3)
1

[^/,^\s]+?\.\S+?\.\S+?(?=/|\s)

凡是域名,都是 xxx.yyy.zzz这种格式,主域名为www居多,子域名就可多了。

你试试这个,绝对可以

 

如果只统计某个已知的域名,比如cnblogs.com 可以这样:

[^/,^\s]+?\.cnblogs\.com(?=/|\s)

收获园豆:10
jiulang | 园豆:437 (菜鸟二级) | 2018-02-06 11:07

如果,域名未知,可否有办法?

支持(0) 反对(0) BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-06 11:50

@BUTTERAPPLE: 

未知域名就用 [^/,^\s]+?\.\S+?\.\S+?(?=/|\s)

支持(0) 反对(0) jiulang | 园豆:437 (菜鸟二级) | 2018-02-06 11:51
1

[\da-zA-Z.]?Domain[/\da-zA-Z]?

特殊情况下可能会有问题,具体要看你的数据

收获园豆:10
nicky0227 | 园豆:1069 (小虾三级) | 2018-02-06 11:26

匹配结果:

支持(0) 反对(0) nicky0227 | 园豆:1069 (小虾三级) | 2018-02-06 11:29

@nicky0227: 如果不提供Domain,是否有解决办法?

支持(0) 反对(0) BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-06 11:35

@BUTTERAPPLE: 很难吧,规律性不强,我举个例子:im.cat.com和www.im.cat 这两个url不是同一个Domain,但是均会被im.cat匹配

支持(0) 反对(0) nicky0227 | 园豆:1069 (小虾三级) | 2018-02-06 11:43

@nicky0227: 使用你的这个会,使用我下面回答的那个正则则不会。我就想一次性像把其匹配出来,好像还是要分几步。先把Url匹配出来,遍历结果加入到HashSet中,然后再进行操作。

支持(0) 反对(0) BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-06 11:45
0

使用这个可以^(?:http(?:s)?:\/\/)?(?:[^\.]+\.)?cnblogs\.com$匹配如下

https://cnblogs.com
http://www.cnblogs.com
http://cnblogs.com
https://cnblogs.com
www.cnblogs.com
cnblogs.com

但是前提是我需要提供Domain!!

BUTTERAPPLE | 园豆:3190 (老鸟四级) | 2018-02-06 11:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册