I am making my own packet capture to study the network. I was writing a process to parse Ethernet frames in that. When the raw data received by the socket is converted into a character string, the MAC address is It is acquired without the semicolon ":" inserted.
I want to insert a semicolon
000c29ecc97a
↓ I want to do this ↓
00:0c:29:ec:c9:7a
Since it is a string list, should I divide it into sublists of 2 characters each and join with ":"? When I googled it, I found zip (\ * [iter (s)] * n) as a technique to divide it into n-character sublists.
Insert a semicolon by splitting and joining
>>> s = '000c29ecc97a'
>>> zip(*[iter(s)]*2)
>>> [('0', '0'), ('0', 'c'), ('2', '9'), ('e', 'c'), ('c', '9'), ('7', 'a')]
# ":"Connect with!
>>> ':'.join(map(''.join, zip(*[iter(s)]*2)))
'00:0c:29:ec:c9:7a'
':'.join(map(''.join, zip(*[iter(s)]*2)))But***It's hard to read***。
It's a good technique, but it's unpleasant because it's hard to understand without knowing it.
The next thing I came up with was how to replace it with a regular expression.
#### **`Insert a semicolon with a regular expression`**
```pycon
>>> import re
>>> s = '000c29ecc97a'
>>> raw_mac_ptn = r'([0-9A-F]{2})(?!$)'
>>> mac_addr = re.sub(raw_mac_ptn, r'\1:', s)
>>> mac_addr
'00:0c:29:ec:c9:7a'
I wonder if this one is easier to see. Negative look-ahead (?! $) Is important so that ":" is not inserted at the end.
Recommended Posts