Skip to main content
 首页 » 编程设计

python之使用正则表达式从单行文本中提取主机名

2025年04月02日27java哥

我正在尝试编写一个 Python 脚本,从其 DNS 中提取所有 Google 云计算子网。此处有更多相关信息:

https://cloud.google.com/compute/docs/faq#where_can_i_find_short_product_name_ip_ranges

到目前为止,我可以毫无问题地提取各个主机名的 TXT 记录列表作为基本字符串。

import dns.resolver 
 
# Set the resolver 
my_resolver = dns.resolver.Resolver() 
my_resolver.nameservers = ['8.8.8.8'] 
 
answer = my_resolver.query('_cloud-netblocks.googleusercontent.com', 'TXT') 
 
for rdata in answer: 
    for txt_string in rdata.strings: 
        txt_record = txt_string 

这给我留下了一串

v=spf1 include:_cloud-netblocks1.googleusercontent.com include:_cloud-netblocks2.googleusercontent.com include:_cloud-netblocks3.googleusercontent.com include:_cloud-netblocks4.googleusercontent.com include:_cloud-netblocks5.googleusercontent.com ?all 

我想做的是使用 re.match 从这个初始响应中提取 5 个主机名,这样我就可以进行连续查找并去除子网,然后将它们放入一个数组中。到目前为止,我在正则表达式方面所做的所有努力都不是那么......很棒......我想知道是否有人会提供一些指导?谢谢!

编辑:

这是为需要收集所有 Google 云 IP 的任何其他人准备的完整脚本。

import dns.resolver, re 
 
# Set the resolver 
my_resolver = dns.resolver.Resolver() 
my_resolver.nameservers = ['8.8.8.8'] 
 
answer = my_resolver.query('_cloud-netblocks.googleusercontent.com', 'TXT') 
 
for rdata in answer: 
    for txt_string in rdata.strings: 
        txt_record = txt_string 
 
# Extract hostnames into array 
hostnames = [x.split(":")[1] for x in txt_record.split() if ":" in x] 
total_subnets = [] 
 
for host in hostnames: 
    answer = my_resolver.query(host, 'TXT') 
 
    for rdata in answer: 
        for txt_string in rdata.strings: 
            txt_record = txt_string 
 
    ip4_subnets = re.findall(r'ip4:(\S+)', txt_record) 
    ip6_subnets = re.findall(r'ip6:(\S+)', txt_record) 
 
    for subnet in ip4_subnets: 
        total_subnets.append(subnet) 
 
    for subnet in ip6_subnets: 
        total_subnets.append(subnet) 
 
print total_subnets 

请您参考如下方法:

你不需要为此使用正则表达式,使用 split 两次并理解:

s = "v=spf1 include:_cloud-netblocks1.googleusercontent.com include:_cloud-netblocks2.googleusercontent.com include:_cloud-netblocks3.googleusercontent.com include:_cloud-netblocks4.googleusercontent.com include:_cloud-netblocks5.googleusercontent.com ?all" 
print([x.split(":")[1] for x in s.split() if ":" in x]) 
# => ['_cloud-netblocks1.googleusercontent.com',  
#     '_cloud-netblocks2.googleusercontent.com', 
#     '_cloud-netblocks3.googleusercontent.com', 
#     '_cloud-netblocks4.googleusercontent.com', 
#     '_cloud-netblocks5.googleusercontent.com'] 

参见 demo here

详细信息:

  • s.split() - 用空格分割
  • if ":"in x - 只获取那些带有 : 的条目
  • x.split(":")[1] - 用 : 拆分上述条目并获取第二个 block

当然,如果您愿意,可以使用正则表达式:

include:(\S+) 

参见 demo .

这将匹配 include: 并将 1+ 个非空白符号捕获到第 1 组中。re.findall 将为您获取列表(re.findall (r'include:(\S+)', s)).