2016-07-28 8 views
2

Я пытаюсь написать скрипт Python, вытаскивая все подсети Google Cloud Compute из своего DNS. Более подробная информация об этом здесь:Вытягивание имен хостов из одной строки текста с регулярным выражением

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

До сих пор, я могу вытащить список записей TXT отдельных хостов в basestring без проблем.

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 хостов из этого первоначального ответа, так что я могу сделать последовательную Lookups и раздеть подсети затем помещают их в массив. До сих пор все мои усилия с регулярным выражением не были такими ... великими ... Мне было интересно, даст ли кто-нибудь указания? Благодаря!

Edit:

Вот полный сценарий для тех, кто еще с необходимостью собрать все компании Google Cloud 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 

ответ

1

Вам не нужно использовать регулярное выражение для этого используйте 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] - расщепляет выше записи с : и получает вторую порцию

Конечно, если вы хотите, вы можете использовать регулярные выражения:

include:(\S+) 

См. demo.

Это будет соответствовать include: и будет захватывать 1 + не-пробельные символы в группу 1. re.findall предоставит вам список (re.findall(r'include:(\S+)', s)).

+1

Отлично! Отлично! Спасибо! – user2421173