使用Python正则表达式统计域名中的元素数量
用正则统计域名元素数量:问题分析与解决方案
首先明确说:这绝对不是强行使用正则的场景!域名解析本来就是正则的经典应用场景之一,你之前只是卡在了正则模式的细节上,调整思路就能轻松搞定。
先拆解你之前的正则问题:
你的模式r"^.*//(([^./]+\.)+)/.*$"匹配失败的核心原因,在于([^./]+\.)+这个部分——它要求每一段域名都必须以点结尾,但域名的最后一段(比如例子里的uk)后面跟着的是/,没有点,导致整个模式在这里卡壳,无法完成匹配。另外,^.*//的贪婪匹配虽然大部分时候没问题,但如果遇到带多个//的特殊URL,可能会出现预期外的匹配结果,不过这属于次要问题。
接下来给你几个可行的方案,从直观易读的混合方案到纯正则方案都有,你可以按需选择:
方案一:先提取域名,再分割统计(可读性拉满,日常开发首选)
这个思路和你最初的方法类似,但用正则精准提取域名部分后,再用字符串分割统计,代码清晰易懂,维护起来也方便:
import re url = "http://news.bbc.co.uk/foo/bar/xyzzy.html" # 匹配http/https开头的URL,提取//之后到第一个/之前的域名部分 domain_match = re.search(r"^https?://([^/]+)", url) if domain_match: domain = domain_match.group(1) # 按点分割域名,统计元素数量 element_count = len(domain.split('.')) print(element_count) # 输出4
方案二:纯正则匹配所有域名元素,统计次数
如果你坚持想用正则完成全部统计流程,可以用re.findall匹配域名里的每一段元素,再统计匹配结果的长度:
import re url = "http://news.bbc.co.uk/foo/bar/xyzzy.html" # 先提取域名部分,再匹配所有非.非/的元素 domain = re.search(r"^https?://([^/]+)", url).group(1) elements = re.findall(r"[^./]+", domain) print(len(elements)) # 输出4
或者用更紧凑的正则正向预查,直接定位域名区域内的元素:
import re url = "http://news.bbc.co.uk/foo/bar/xyzzy.html" # 匹配//之后到第一个/之前的所有域名元素 elements = re.findall(r"(?<=//)[^./]+(?=[./])|(?<=//[^./]+\.)[^./]+(?=/)", url) print(len(elements)) # 输出4
方案三:通过统计点的数量间接得到元素数
还有个巧方法:域名的元素数 = 域名里的点的数量 + 1。我们可以用正则统计//之后到第一个/之间的点的数量,再加1即可:
import re url = "http://news.bbc.co.uk/foo/bar/xyzzy.html" # 统计域名区域内的点的数量 dot_count = len(re.findall(r"(?<=//)[^/]*\.(?=[^/]*$)", url)) element_count = dot_count + 1 print(element_count) # 输出4
最后再啰嗦一句:工具是为解决问题服务的,没必要为了用正则而用正则——比如方案一的代码可读性最高,其实是日常开发里的首选;但你跳出舒适区尝试正则的思路非常棒,这正是提升编程技能的好途径!
内容的提问来源于stack exchange,提问作者Hannu
相关产品推荐
相关产品推荐

