【问题标题】:Building a regex to extract domains ONLY构建正则表达式以仅提取域
【发布时间】:2021-04-21 23:23:43
【问题描述】:

我希望在 python 中创建一个正则表达式,以便仅从本文底部的 URL 集中提取域。在应用Series.str.extract() 之前,我一直在使用https://regexr.com/ 来测试我的正则表达式。到目前为止,我已经能够非常接近,但看起来第一个字符(www 中的第一个'w',其中包含一个)没有被捕获。我到目前为止的正则表达式是这样的:

[^\/\/](\w*.\w*.com|\w*.\w*.org|\w*.\w*.cc|\w*.\w*.ly)

如何将其从 http://css-cursor.techstream.org 修改为仅 css-cursor.techstream.org

'https://www.amazon.com/Technology-Ventures-Enterprise-Thomas-Byers/dp/0073523429',
 'http://www.interactivedynamicvideo.com/',
 'http://www.nytimes.com/2007/11/07/movies/07stein.html?_r=0',
 'http://evonomics.com/advertising-cannot-maintain-internet-heres-solution/',
 'HTTPS://github.com/keppel/pinn',
 'Http://phys.org/news/2015-09-scale-solar-youve.html',
 'https://iot.seeed.cc',
 'http://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html',
 'http://beta.crowdfireapp.com/?beta=agnipath',
 'https://www.valid.ly?param',
 'http://css-cursor.techstream.org'

【问题讨论】:

    标签: python regex capture


    【解决方案1】:

    正则表达式是否是硬性要求,因为您需要将它与现有的正则表达式结合起来?如果没有,标准库中有一个简单的工具可以做到这一点:

    from urllib.parse import urlparse
    
    urls = [
        'https://www.amazon.com/Technology-Ventures-Enterprise-Thomas-Byers/dp/0073523429',
        'http://www.interactivedynamicvideo.com/',
        'http://www.nytimes.com/2007/11/07/movies/07stein.html?_r=0',
        'http://evonomics.com/advertising-cannot-maintain-internet-heres-solution/',
        'HTTPS://github.com/keppel/pinn',
        'Http://phys.org/news/2015-09-scale-solar-youve.html',
        'https://iot.seeed.cc',
        'http://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html',
        'http://beta.crowdfireapp.com/?beta=agnipath',
        'https://www.valid.ly?param',
        'http://css-cursor.techstream.org',
    ]
    
    domains = [urlparse(url).netloc for url in urls]
    print(domains)
    

    好吧,我猜正则表达式更快:

    >>> netloc = re.compile(r'^https?://([^/?^]+)', flags=re.I)                                                                                                    
    >>> %timeit [netloc.match(url).group(1) for url in urls]                                                                                                       
    5.66 µs ± 97.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    >>> %timeit [urlparse(url).netloc for url in urls]                                                                                                             
    23.3 µs ± 3.68 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    

    【讨论】:

    • 嗨!作为练习使用正则表达式的练习的一部分,我被要求这样做。感谢您向我展示 urlparse!目前正在研究什么是非捕获组。
    • @Willy_Golden 学习一个强大的工具,玩得开心。如果您难以掌握它们,您可以尝试不同的观点:并练习将给定的正则表达式转换为有限状态自动机。我发现从不同的角度接近一个主题有助于形成正确的直觉。和形式语言理论can be very amusing
    【解决方案2】:

    对于示例数据,您可以对 com org lycc 使用交替,并将点转义以匹配它的字面意思。

    要匹配css-cursor.techstream.org,您可以使用重复组匹配-.

    请注意,[^\/\/][^/] 相同,并且匹配除 / 之外的任何字符

    \w+(?:[.-]\w+)*\.(?:ly|org|com|cc)\b
    
    • \w+ 匹配 1+ 个单词字符
    • (?:[.-]\w+)* 可选择重复匹配 .- 和 1+ 个单词字符
    • \. 匹配一升点(注意转义)
    • (?:ly|org|com|cc)非捕获组,匹配任意一个选项
    • \b 防止部分匹配的单词边界

    Regex demo

    如果你还想匹配协议,你可以为你想要的字符串使用一个捕获组。

    \bhttps?://(\w+(?:[.-]\w+)*\.(?:ly|org|com|cc))\b
    

    Regex demo

    【讨论】:

      【解决方案3】:

      根据 regexr.com,这应该可以满足您的要求并且更简单: (?<=\/\/)([^/?']*) 。毕竟,域实际上是从 // 到下一个 / 或 ?或字符串结尾。

      【讨论】:

      • 我刚刚对此进行了测试,但它实际上不起作用!您的解决方案似乎包括 bacslahses,在一种情况下,http!
      • 您是单独测试字符串,还是包括撇号?您可以为撇号修复它。
      【解决方案4】:

      我把它改成了下面的表达式:

      [^\/\/]([\w\-.]*\.(?:org|com|cc|ly))

      1. TLD 之前的 . 现在使用 \ 进行转义(\.,表示字符 . 而不是“每个字符”)。
      2. 我已将-. 添加到主机名(不仅是\w)。
      3. 我已将 TLD(org、com、cc、ly)分组到一个非捕获组 ((?:...)) - 只是为了使正则表达式看起来更清晰并消除重复。

      【讨论】:

      • sre_constants.error: bad character range \w-. at position 9。 (您需要对- 进行反冲转义或将其放在字符类的开头或结尾。)
      【解决方案5】:

      我添加了文字点。和 - 破折号到正则表达式

      data=['https://www.amazon.com/Technology-Ventures-Enterprise-Thomas- 
       Byers/dp/0073523429',
       'http://www.interactivedynamicvideo.com/',
       'http://www.nytimes.com/2007/11/07/movies/07stein.html?_r=0',
       'http://evonomics.com/advertising-cannot-maintain-internet-heres-solution/',
       'HTTPS://github.com/keppel/pinn',
       'Http://phys.org/news/2015-09-scale-solar-youve.html',
       'https://iot.seeed.cc',
       'http://www.bfilipek.com/2016/04/custom-deleters-for-c-smart-pointers.html',
       'http://beta.crowdfireapp.com/?beta=agnipath',
       'https://www.valid.ly?param',
       'http://css-cursor.techstream.org']
      
      import re
      
      pattern = re.compile(r'https?://([\w.\.\-]+)')
      
      for data in data:
           match = pattern.match(data)
           if match:
               print(match.group(1))
      

      输出:

      www.amazon.com
      www.interactivedynamicvideo.com
      www.nytimes.com
      evonomics.com
      iot.seeed.cc
      www.bfilipek.com
      beta.crowdfireapp.com
      www.valid.ly
      css-cursor.techstream.org
      

      【讨论】:

        猜你喜欢
        • 2016-04-21
        • 1970-01-01
        • 2015-09-27
        • 2014-10-31
        • 1970-01-01
        • 2023-03-19
        • 2014-11-11
        • 2016-08-18
        • 1970-01-01
        相关资源
        最近更新 更多