【问题标题】:Extract all domains from text从文本中提取所有域
【发布时间】:2014-01-19 08:58:40
【问题描述】:

我需要从字符串中提取域。我有一个有效的正则表达式,它已经过测试,但是我无法让它与以下代码一起使用。可能我在这里遗漏了一些明显的东西

mytext = "I want to extract some domains like foo.com, bar.net or http://foobar.net/ etc"
myregex = r'^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$'
foo = re.findall(myregex, mytext)
print foo

当我想要类似的东西时,我只是打印出一个空列表

['foo.com','bar.net','foobar.net']

【问题讨论】:

标签: python regex


【解决方案1】:

移除锚点,使群组不被捕获:

r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}'

^$ 锁定您的表达式以匹配整个字符串。当模式包含捕获组时,re.findall() 也会改变行为;您想在此处列出要求没有此类组的整个比赛。 (...) 是捕获组,(?:...) 是非捕获组。

演示:

>>> myregex = r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}'
>>> re.findall(myregex, mytext)
['foo.com', 'bar.net', 'foobar.net']

【讨论】:

    【解决方案2】:

    这里的问题是您的正则表达式在开头包含 ^ 并在结尾包含 $,这意味着它只匹配同时开始和结束字符串的域(即只是一个域)。

    例如,它将匹配“www.stackoverflow.com”,但不匹配“this is a question on www.stackoverflow.com”或“www.stackoverflow.com is great”。

    如果您只是从正则表达式中删除 ^ 和 $,它应该可以正常工作。 Here's a small example

    【讨论】:

      【解决方案3】:

      问题是在正则表达式的开头包含^,在结尾包含$。这使得它仅在域是整个字符串时才匹配。在这里,您想查看字符串中的匹配项。尝试像这样改变它

      myregex = r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}'
      

      编辑

      @Martijn 指出这里需要使用非捕获组来获得指定的输出。

      【讨论】:

      • 请注意,OP 使用的是re.findall(),它要么返回一个元组列表(模式中的每个匹配组),要么如果只有一个组,则返回一个组捕获列表,或者如果没有组,则显示整个匹配项的列表。使用此模式中的捕获组,这意味着给定样本输入的结果是 [('foo.', 'oo'), ('bar.', 'ar'), ('foobar.', 'oobar')]
      猜你喜欢
      • 2016-01-06
      • 1970-01-01
      • 2013-07-19
      • 2013-10-16
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      • 2017-10-05
      • 1970-01-01
      相关资源
      最近更新 更多