Python 使用多种字符串格式解析挑战
我试图解析设备日志,但格式不一致 例如:Python 使用多种字符串格式解析挑战,python,regex,Python,Regex,我试图解析设备日志,但格式不一致 例如: Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70 Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70 我想提取Mac地址、通道和RSSI值 不幸的是,在候选值变为10或更高之后,空格被省略 我试图将其标记化,但我几乎不理解这个过程 def clean(string): result = ""
Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70
Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70
我想提取Mac地址、通道和RSSI值不幸的是,在候选值变为10或更高之后,空格被省略 我试图将其标记化,但我几乎不理解这个过程
def clean(string):
result = ""
for i,char in enumerate(line):
if char == " ":
if string[i+1].isdigit() or string[i+1] == " ":
continue
result += char
return result
def tokenize(string):
result = []
previous = 0
for i,char in enumerate(string):
if char == " ":
result.append(string[previous:i])
previous = i+1
elif i == len(string)-1:
result.append(string[previous:i+1])
return result
我只将最后一列(RSSI)作为输出如果要使用模式,可以使用3个捕获组,1个用于mac地址,1个用于通道,1个用于RSSI值:
Roam candidate# ?\d+ ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) on channel (\d+) +RSSI: (-?\d+)
小部分:
匹配漫游候选#,可选空格和1+位数漫游候选#?\d+
捕获组1,匹配mac地址((?:[0-9A-Fa-f]{2}[:-]){5}(?[0-9A-Fa-f]){2})
在频道上匹配,空格后按2组1+数字捕获在频道上(\d+)+
匹配RSSI:、空格并在第3组中捕获可选的RSSI:(?\d+)
和1+位数-
import re
strings = ["Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70", "Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70"]
regex = r"Roam candidate# ?\d+ ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) on channel (\d+) +RSSI: (-?\d+)"
for s in strings:
print(re.findall(regex, s, re.M))
结果
[('F4:CF:E2:5E:73:3F','161','-70')]
[('F4:CF:E2:62:02:2F','11','70')]
如果要使用模式,可以使用3个捕获组,1个用于mac地址,1个用于通道,1个用于RSSI值:
Roam candidate# ?\d+ ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) on channel (\d+) +RSSI: (-?\d+)
小部分:
匹配漫游候选#,可选空格和1+位数漫游候选#?\d+
捕获组1,匹配mac地址((?:[0-9A-Fa-f]{2}[:-]){5}(?[0-9A-Fa-f]){2})
在频道上匹配,空格后按2组1+数字捕获在频道上(\d+)+
匹配RSSI:、空格并在第3组中捕获可选的RSSI:(?\d+)
和1+位数-
import re
strings = ["Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70", "Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70"]
regex = r"Roam candidate# ?\d+ ((?:[0-9A-Fa-f]{2}[:-]){5}(?:[0-9A-Fa-f]){2}) on channel (\d+) +RSSI: (-?\d+)"
for s in strings:
print(re.findall(regex, s, re.M))
结果
[('F4:CF:E2:5E:73:3F','161','-70')]
[('F4:CF:E2:62:02:2F','11','70')]
对于regex,它的工作原理如下:
import re
s1="Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70"
s2="Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70"
patt= re.compile('(?P<mac>[0-9A-F]{2}(:[0-9A-F]{2}){5}).*?channel (?P<channel>[0-9]*).*?RSSI:\s*(?P<rssi>-?[0-9]*)', re.I)
matcher= patt.search(s1)
print(matcher.group('mac'))
print(matcher.group('channel'))
print(matcher.group('rssi'))
第二行:
F4:CF:E2:62:02:2F
11
-70
对于regex,它的工作原理如下:
import re
s1="Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70"
s2="Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70"
patt= re.compile('(?P<mac>[0-9A-F]{2}(:[0-9A-F]{2}){5}).*?channel (?P<channel>[0-9]*).*?RSSI:\s*(?P<rssi>-?[0-9]*)', re.I)
matcher= patt.search(s1)
print(matcher.group('mac'))
print(matcher.group('channel'))
print(matcher.group('rssi'))
第二行:
F4:CF:E2:62:02:2F
11
-70
另一种正则表达式方法:
import re
lines = '''Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70
Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70'''
pat = re.compile(r'(?<=#)\s*\d+\s+((?:[A-F0-9]{2}:){5}[A-F0-9]{2}) .*channel\s+(\d+)\s+RSSI:\s+(-?\d+)', re.I)
for line in lines.split('\n'):
print(pat.findall(line))
另一种正则表达式方法:
import re
lines = '''Roam candidate# 9 F4:CF:E2:5E:73:3F on channel 161 RSSI: -70
Roam candidate#10 F4:CF:E2:62:02:2F on channel 11 RSSI: -70'''
pat = re.compile(r'(?<=#)\s*\d+\s+((?:[A-F0-9]{2}:){5}[A-F0-9]{2}) .*channel\s+(\d+)\s+RSSI:\s+(-?\d+)', re.I)
for line in lines.split('\n'):
print(pat.findall(line))
简单的事情可能更好
r”(?i)([a-f0-9]{2}(?:[a-f0-9]{2})+\s.*\s(\d+)\s.*\s(-)\d+)
扩大
(?i)
( # (1 start)
[a-f0-9]{2}
(?: : [a-f0-9]{2} )+
) # (1 end)
\s .*? \s
( \d+ ) # (2)
\s .*? \s
( -? \d+ ) # (3)
简单的事情可能更好
r”(?i)([a-f0-9]{2}(?:[a-f0-9]{2})+\s.*\s(\d+)\s.*\s(-)\d+)
扩大
(?i)
( # (1 start)
[a-f0-9]{2}
(?: : [a-f0-9]{2} )+
) # (1 end)
\s .*? \s
( \d+ ) # (2)
\s .*? \s
( -? \d+ ) # (3)
下面是一个使用命名捕获组的正则表达式。您可以将鼠标悬停在对象上以了解它们的功能:下面是一个使用命名捕获组的正则表达式。您可以将鼠标悬停在对象上以了解它们的作用:在我的情况下,我需要从日志文件中提取许多字符串。这些值来自包含“ConstructionNeightarCacheFromBeacon”的行,因此我将仅对这些值进行筛选lines@EricGarnel因此,在我的例子中,如果你想从字面上匹配开始,我需要从日志文件中提取许多字符串。这些值来自包含“ConstructionNeightarCacheFromBeacon”的行,因此我将仅对这些值进行筛选lines@EricGarnel因此,您希望从字面上匹配开始,这正是我要查找的输出,但我一直在研究如何将包含特定单词的行读入数组(代替示例中的lines语句)。其中包含单词beaconcache的示例行。谢谢,我就是这样解决的:#/usr/bin/python#import sys,re arr=[],open('file.txt',r')作为f:for f.readlines()中的行:如果行中的'constructNeightRCacheFromBeaConCache':#print(line)arr.append(line)regex=r“Roam候选者#?\d+(?:[0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]){f]){2}在通道上(+RSSI:-){对于arr:print(re.findall(regex,s,re.M))中的s,这正是我要寻找的输出,但我一直在研究如何将包含特定单词的行读入数组(代替示例中的lines语句)。其中包含单词beaconcache的示例行。谢谢,我就是这样解决的:#/usr/bin/python#import sys,re arr=[],open('file.txt',r')作为f:for f.readlines()中的行:如果行中的'constructNeightRCacheFromBeaConCache':#print(line)arr.append(line)regex=r“Roam候选者#?\d+(?:[0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]){f]){2}在通道上(+RSSI:-){对于arr中的s:打印(关于findall(regex,s,re.M))