0

「10.[3-25].0.X」のようなものを、このルールで記述された IP アドレスの実際のリストに解析できるようにしたいので、上記の例のルールの場合、リストは [10.3.0.0, 10.3] になります。 .0.1....10.25.0.255]。それを行う最良の方法は何ですか?これまでのところ、私が思いついたのは、次の見栄えの悪い関数だけです。

wc = ''.join(wc.split()).upper()
wc = re.sub(r'(?<![\[-])(\d+)(?![\]-])', r'[\1-\1]', wc)
wc = re.sub(r'X', r'[0-255]', wc).split('.')
ips = []
for i in range(int(re.findall(r'(\d+)-(\d+)', wc[0])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[0])[0][1]) + 1): 

    for j in range(int(re.findall(r'(\d+)-(\d+)', wc[1])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[1])[0][1]) + 1): 

        for k in range(int(re.findall(r'(\d+)-(\d+)', wc[2])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[2])[0][1]) + 1):

            for p in range(int(re.findall(r'(\d+)-(\d+)', wc[3])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[3])[0][1]) + 1):

                ips.append(str(i) + '.' + str(j) + '.' + str(k) + '.' + str(p))

return ips

改善のアイデアをいただければ幸いです。

4

3 に答える 3

1

を使用した例を次に示しますitertools.product。アイデアは、最初に「テンプレート」(たとえば、1.5.123.2-5、23.10-20.X.12、...)をオクテットごとに評価し(それぞれが値のリストを生成します)、次にそれらのリストのデカルト積を取得することです.

import itertools
import re
import sys

def octet(s):
    """
    Takes a string which represents a single octet template.
    Returns a list of values. Basic sanity checks.
    """
    if s == 'X':
        return xrange(256)
    try:
        low, high = [int(val) for val in s.strip('[]').split('-')]
        if low > high or low < 0 or high > 255:
            raise RuntimeError('That is no valid range.')
        return xrange(low, high + 1)
    except ValueError as err:
        number = int(s)
        if not 0 <= number <= 255:
            raise ValueError('Only 0-255 allowed.')
        return [number]

if __name__ == '__main__':
    try:
        template = sys.argv[1]
        octets = [octet(s) for s in template.split('.')]
        for parts in itertools.product(*octets):
            print('.'.join(map(str, parts)))
    except IndexError as err:
        print('Usage: %s IP-TEMPLATE' % (sys.argv[0]))
        sys.exit(1)

(小) 例:

$ python ipregex.py '1.5.123.[2-5]'
1.5.123.2
1.5.123.3
1.5.123.4
1.5.123.5

$ python ipregex.py '23.[19-20].[200-240].X'
23.19.200.0
23.19.200.1
23.19.200.2
...
23.20.240.253
23.20.240.254
23.20.240.255   
于 2013-10-09T18:44:36.900 に答える
1

これをもっと簡単にすることができます。

まず、まったく同じことを 4 回書く代わりに、ループまたは listcomp を使用します。

ranges = [range(int(re.findall(r'(\d+)-(\d+)', wc[i])[0][0]), 
                int(re.findall(r'(\d+)-(\d+)', wc[i])[0][1]) + 1)
          for i in range(4)]

ネストされたループをデカルト積のフラット ループに変換することもできます。

for i, j, k, p in itertools.product(*ranges):

そして、その長い文字列連結の混乱を単純な形式または join 呼び出しに変えることができます:

ips.append('{}.{}.{}.{}'.format(i, j, k, p)) # OR
ips.append('.'.join(map(str, (i, j, k, p))))

つまり、最初から 4 つのコンポーネントを分割する必要はありません。

for components in itertools.product(*ranges):
    ips.append('{}.{}.{}.{}'.format(*components)) # OR
    ips.append('.'.join(map(str, components)))

これでループは非常に簡単になったので、リストコンプに変換できます。

ips = ['{}.{}.{}.{}'.format(*components)
       for components in itertools.product(*ranges)]
于 2013-10-09T18:44:59.797 に答える