简体   繁体   中英

split string every nth character and append ':'

I've read some switch MAC address table into a file and for some reason the MAC address if formatted as such:

'aabb.eeff.hhii'

This is not what a MAC address should be, it should follow: 'aa:bb:cc:dd:ee:ff'

I've had a look at the top rated suggestions while writing this and found an answer that may fit my needs but it doesn't work

satomacoto's answer

The MACs are in a list, so when I run for loop I can see them all as such:

Current Output

['8424.aa21.4er9','fa2']
['94f1.3002.c43a','fa1']

I just want to append ':' at every 2nd nth character, I can just remove the '.' with a simple replace so don't worry about that

Desired output

['84:24:aa:21:4e:r9','fa2']
['94:f1:30:02:c4:3a','fa1']

My code

info = []
newinfo = []
file = open('switchoutput')
newfile = file.read().split('switch')
macaddtable = newfile[3].split('\\r')
for x in macaddtable:
   if '\\n' in x:
       x = x.replace('\\n', '')
   if carriage in x:
       x = x.replace(carriage, '')
   if '_#' in x:
       x = x.replace('_#', '')
   x.split('/r')
   info.append(x)
for x in info:
   if "Dynamic" in x:
      x = x.replace('Dynamic', '')
   if 'SVL' in x:
      x = x.replace('SVL', '')
   newinfo.append(x.split(' '))
for x in newinfo:
   for x in x[:1]:
       if '.' in x:
           x = x.replace('.', '')
   print(x)

Borrowing from the solution that you linked , you can achieve this as follows:

macs = [['8424.aa21.4er9','fa2'], ['94f1.3002.c43a','fa1']]

macs_fixed = [(":".join(map(''.join, zip(*[iter(m[0].replace(".", ""))]*2))), m[1]) for m in macs]

Which yields:

[('84:24:aa:21:4e:r9', 'fa2'), ('94:f1:30:02:c4:3a', 'fa1')]

If you like regular expressions:

import re

dotted = '1234.3456.5678'
re.sub('(..)\.?(?!$)', '\\1:', dotted)
# '12:34:34:56:56:78'

The template string looks for two arbitrary characters '(..)' and assigns them to group 1. It then allows for 0 or 1 dots to follow '\\.?' and makes sure that at the very end there is no match '(?!$)'. Every match is then replaced with its group 1 plus a colon.

This uses the fact that re.sub operates on nonoverlapping matches.

x = '8424.aa21.4er9'.replace('.','')
print(':'.join(x[y:y+2] for y in range(0, len(x) - 1, 2)))
>> 84:24:aa:21:4e:r9

Just iterate through the string once you've cleaned it, and grab 2 string each time you loop through the string. Using range() third optional argument you can loop through every second elements. Using join() to add the : in between the two elements you are iterating.

You can use re module to achieve your desired output.

import re

s = '8424.aa21.4er9'
s = s.replace('.','')
groups = re.findall(r'([a-zA-Z0-9]{2})', s)
mac = ":".join(groups)
#'84:24:aa:21:4e:r9'

Regex Explanation

  • [a-zA-Z0-9] : Match any alphabets or number
  • {2} : Match at most 2 characters.

This way you can get groups of two and then join them on : to achieve your desired mac address format

wrong_mac = '8424.aa21.4er9'
correct_mac = ''.join(wrong_mac.split('.'))

correct_mac  = ':'.join(correct_mac[i:i+2] for i in range(0, len(correct_mac), 2))

print(correct_mac)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM