re#
メソッド#
match
文字列の先頭で正規表現パターンにマッチした場合、対応するマッチオブジェクトを返す。search
文字列を走査し、正規表現パターンがマッチする最初の場所を探し、対応するマッチオブジェクトを返します。findall
テンプレートとのすべての一致を検索します。結果の文字列をリストとして返す。finditer
テンプレートと一致するものを検索し、イテレータを返す。compile
正規表現をコンパイルします。fullmatch
文字列全体が正規表現パターンにマッチする場合、対応するマッチオブジェクトを返す。sub
正規表現にマッチした文字列を置換する。split
正規表現にマッチした箇所で文字列を分割する。
Info
正規表現にマッチしなかった場合はNoneをかえします。
基本的なマッチ例#
import re
log = "RP/0/0/CPU0:Apr 22 15:49:42.020 JST: mpls_ldp[1181]: %ROUTING-LDP-5-NBR_CHANGE : VRF 'default' (0x60000000), Neighbor 2.2.2.2:0 is UP (IPv4 connection)"
match = re.search(r'Neighbor (\d+.\d+.\d+.\d+)', log)
print(match)
# マッチオブジェクトを返す。
# <re.Match object; span=(109, 125), match='Neighbor 2.2.2.2'>
print(match.group())
# 文字列は.group()で取得
# Neighbor 2.2.2.2
# グループ0を指定しても同じ結果を返す
print(match.group(0))
# 他の番号は、関連するグループの内容を返す
print(match.group(1))
# 既存のグループの数よりも大きいグループ番号で `group` メソッドを呼び出すと、IndexError
# print(match.group(2))
# 複数のグループ番号を持つメソッドを呼び出すと、結果は一致に対応する文字列を持つタプル
print(match.group(0,1))
# ('Neighbor 2.2.2.2', '2.2.2.2')
groupdict()#
正規表現で(?P<key>pattern)
を用いて、マッチしたオブジェクトには groupdict()メソッドで辞書を取得できます。
import re
config = """
router static address-family ipv4 unicast 1.1.1.1/32 TenGigE0/0/0/0 1.1.1.2 bfd fast-detect minimum-interval 500 multiplier 3
router static address-family ipv6 unicast 1:1:1:1::2/128 TenGigE0/0/0/0 10:10:10:10::1 bfd fast-detect minimum-interval 500 multiplier 3
"""
static_match = re.search(
r'router static address-family ipv(4|6) unicast '
r'(?P<dst_address>\S+) '
r'(?P<interface>\S+) '
r'(?P<next_hop>\S+) '
r'bfd fast-detect minimum-interval '
r'(?P<bfd_interval>\d+) multiplier '
r'(?P<bfd_multiplier>\d+)'
,config)
print(static_match.groupdict())
re.compile#
複数行に分けて正規表現を記述する例1
static_match = re.compile(
r'router static address-family ipv(4|6) unicast '
r'(?P<dst_address>\S+) '
r'(?P<interface>\S+) '
r'(?P<next_hop>\S+) '
r'bfd fast-detect minimum-interval '
r'(?P<bfd_interval>\d+) multiplier '
r'(?P<bfd_multiplier>\d+)'
)
複数行に分けて正規表現を記述する例2
static_pattern = re.compile(
r'''^router\sstatic\saddress-family\sipv6\sunicast\s
# コメントアウトを書けます。
(?P<dst_address>\S+)\s
(?P<interface>\S+)\s
(?P<next_hop>\S+)
bfd\sfast-detect\sminimum-interval\s
(?P<bfd_interval>\d+)\s
(?P<bfd_multiplier>\d+)
''',re.X)
Tip
複数行記述する場例2は三連引用符(トリプルクオーテーション)と、オプション re.X
を使用します。
re.X では空白、コメントアウトは無視されます。正規表現で空白がある場合は\s
にて記述します。
Quote
re.compile() やモジュールレベルのマッチング関数に渡された最新のパターンはコンパイル済みのものがキャッシュされるので、 一度に正規表現を少ししか使わな
show cdp neighbor の処理例#
for 文で読み込んだテキストを一行ずつ処理。 startswithを条件分岐に用いている
import re from pprint import pprint def parse_cdp(filename): result = {} with open(filename) as f: for line in f: # startswith を使用して処理 if line.startswith('Device ID'): neighbor = re.search('Device ID: (\S+)', line).group(1) result[neighbor] = {} elif line.startswith(' IP address'): ip = re.search('IP address: (\S+)', line).group(1) result[neighbor]['ip'] = ip elif line.startswith('Platform'): platform = re.search('Platform: (\S+ \S+),', line).group(1) result[neighbor]['platform'] = platform elif line.startswith('Cisco IOS Software'): ios = re.search('Cisco IOS Software, (.+), RELEASE', line).group(1) result[neighbor]['ios'] = ios return result pprint(parse_cdp('sh_cdp_neighbors_sw1.txt'))