Python 某些正则表达式don';当字符串为多行时,无法正确匹配
我刚开始学习基本编程来解决现实世界的问题。目前,我正在努力使用Python中的一些正则表达式,希望能在这里得到一些帮助 我需要远程登录到网络交换机中,在做其他事情之前获取其固件版本。因此,命令“show switch”的输出如下所示: (请注意,根据主设备和辅助设备上实际运行的特定固件版本,可能会或可能不会显示一行“patchX-X”。) 下面的Python代码用于从上述输出中提取版本。 预期结果将是priVer==“12.3.4.5补丁1-2”和secVer==“12.6.7.8补丁3-4” 奇怪的是,复制并粘贴“show switch”命令的结果,并手动传递给变量“readout”,似乎在使用相同的正则表达式时效果不错:Python 某些正则表达式don';当字符串为多行时,无法正确匹配,python,regex,python-2.7,Python,Regex,Python 2.7,我刚开始学习基本编程来解决现实世界的问题。目前,我正在努力使用Python中的一些正则表达式,希望能在这里得到一些帮助 我需要远程登录到网络交换机中,在做其他事情之前获取其固件版本。因此,命令“show switch”的输出如下所示: (请注意,根据主设备和辅助设备上实际运行的特定固件版本,可能会或可能不会显示一行“patchX-X”。) 下面的Python代码用于从上述输出中提取版本。 预期结果将是priVer==“12.3.4.5补丁1-2”和secVer==“12.6.7.8补丁3-4”
import re
readout = """
SysName: switch1
SysLocation:
SysContact: support@extremenetworks.com, +1 888 257 3000
System MAC: 00:01:02:03:04:05
System Type: X440
SysHealth check: Enabled (Normal)
Recovery Mode: All
System Watchdog: Enabled
Current Time: Mon Dec 31 00:00:00 2000
Timezone: [Auto DST Disabled] GMT Offset: 0 minutes, name is UTC.
Boot Time: Mon Dec 31 00:00:00 2000
Boot Count: 1
Next Reboot: None scheduled
System UpTime: 0 minutes 0 seconds
Current State: OPERATIONAL
Image Selected: primary
Image Booted: primary
Primary ver: 12.3.4.5
patch1-2
Secondary ver: 12.6.7.8
patch3-4
Config Selected: primary.cfg
Config Booted: primary.cfg
"""
def regexCheck():
global priVer
global secVer
global priPatch
global secPatch
global readout
priVer = re.findall(r"(?<=Primary ver:\s{6})\S+",readout)[0]
secVer = re.findall(r"(?<=Secondary ver:\s{4})\S+",readout)[0]
try:
priPatch = re.findall(r"(?<=Primary ver:\s{6}\S{8}\s{19})\S+",readout)[0]
priVer = priVer + " " + priPatch
except IndexError:
print "Oops!IndexError!"
pass
try:
secPatch = re.findall(r"(?<=Secondary ver:\s{4}\S{8}\s{19})\S+",readout)[0]
secVer = secVer + " " + secPatch
except IndexError:
print "Oops!IndexError!"
pass
def main():
regexCheck()
print "Primary Version = " + priVer
print "Secondary Version = " + secVer
main()
因此,我想知道这里是否存在某种“多行字符串格式”问题,但在搜索或毫无根据的试用中没有运气
如果您有任何想法,我们将不胜感激
谢谢
更新:
将iTerm2中的所有行直接复制/粘贴到SublimateText或网页上的此文本框中可能无法保留原始格式,因此我首先readout=readout。替换(“\r\n”,“@\r\n”)
,然后打印readout
,现在看起来如下:
switch1.1 # show switch@
@
SysName: switch1@
SysLocation: @
SysContact: support@extremenetworks.com, +1 888 257 3000@
System MAC: 00:01:02:03:04:05@
System Type: X440@
@
SysHealth check: Enabled (Normal)@
Recovery Mode: All@
System Watchdog: Enabled@
@
Current Time: Mon Dec 31 00:00:00 2000@
Timezone: [Auto DST Disabled] GMT Offset: 0 minutes, name is UTC.@
Boot Time: Mon Dec 31 00:00:00 2000@
Boot Count: 1@
Next Reboot: None scheduled@
System UpTime: 0 minutes 0 seconds @
@
Current State: OPERATIONAL @
Image Selected: primary @
Image Booted: primary @
Primary ver: 12.3.4.5 @
patch1-2@
Secondary ver: 12.6.7.8 @
@
Config Selected: primary.cfg @
Config Booted: primary.cfg @
@
primary.cfg Created by ExtremeXOS version 15.7.1.4@
123456 bytes saved on Mon Dec 31 00:00:00 2000@
switch1.2 #
我认为问题源于脚本处理换行符的方式与编辑器处理换行符的方式不匹配 我运行了您的代码,并将所有“\n”替换为“\r\n”,得到的结果与脚本在交换机上运行时得到的结果相同:
>>> main()
Primary Version = 12.3.4.5 patch1-2
Secondary Version = 12.6.7.8 patch3-4
>>> readout = readout.replace("\n", "\r\n")
>>> main()
Oops!IndexError!
Oops!IndexError!
Primary Version = 12.3.4.5
Secondary Version = 12.6.7.8
请仔细检查telnet会话是否未添加任何您不期望的额外回车。或者更改正则表达式以匹配此值。不要对空格数过于严格。您可以使用
+
来代替。如果您正在读取指向终端的输出,它可能包含CR-LF,而不仅仅是LF。不过,总的来说,这样做是错误的。请参见,例如,g_M的答案。@nhahtdh感谢您的建议,我确实考虑过使用+符号而不是空格数,但regex101警告说,+后视镜中的量词使其为非固定宽度
,这看起来是一个很好的解决方案,但如果您用几句话解释一下您正在做的事情,可能会更好。哇,谢谢,伙计!这比像我这样的业余爱好者更复杂,他用科学怪人的方式讲述一个简单的脚本很容易理解…无论如何,这会返回一些错误,比如“KeyError:None”,这就是d[prev_key]+='{}'。格式(当前行)
告诉我…当我运行Python2.7时,您的代码可能是Python3…加上NHAHDH的帮助,我刚刚计算出在“12.3.4.5”之后,在它得到“\r\n”之前,似乎还有16个空格,所以不确定您的解决方案是否能工作out@Freddy此代码使用您自己的读数
字符串,并提供您的预期输出(没有出现错误)。如果您使用其他读出器
字符串作为输入,则您需要提供该信息,因为我没有其他方法来测试此代码。解释键错误
将是一个简单的解决方案,但在您提供导致它的实际输入字符串之前,这只是猜测。@nHahth代码读起来像普通英语,我很抱歉我不确定您实际需要什么类型的解释。请逐行阅读,拆分为键/值对。如果您不能拆分为键/值对,请跳过空行或将当前的'patch'
行添加到上一个键的值中来处理。@G对于不知道回车符和换行符,我很抱歉,我更新了原始question将提供更多信息,并希望对疑难解答有用。为了检查telnet会话得到了什么,我使用您的方法用@sign替换\r\n并尝试将其可视化。如果我做得对,在“12.3.4.5”后面实际上有16个空格,然后是一个“\r\n”,然后在它点击“patch1-2”之前有19个空格……现在问题变成了“如何更正priPatch=re.findall(r)(?”?
import re
readout = """
SysName: switch1
SysLocation:
SysContact: support@extremenetworks.com, +1 888 257 3000
System MAC: 00:01:02:03:04:05
System Type: X440
SysHealth check: Enabled (Normal)
Recovery Mode: All
System Watchdog: Enabled
Current Time: Mon Dec 31 00:00:00 2000
Timezone: [Auto DST Disabled] GMT Offset: 0 minutes, name is UTC.
Boot Time: Mon Dec 31 00:00:00 2000
Boot Count: 1
Next Reboot: None scheduled
System UpTime: 0 minutes 0 seconds
Current State: OPERATIONAL
Image Selected: primary
Image Booted: primary
Primary ver: 12.3.4.5
patch1-2
Secondary ver: 12.6.7.8
patch3-4
Config Selected: primary.cfg
Config Booted: primary.cfg
"""
def regexCheck():
global priVer
global secVer
global priPatch
global secPatch
global readout
priVer = re.findall(r"(?<=Primary ver:\s{6})\S+",readout)[0]
secVer = re.findall(r"(?<=Secondary ver:\s{4})\S+",readout)[0]
try:
priPatch = re.findall(r"(?<=Primary ver:\s{6}\S{8}\s{19})\S+",readout)[0]
priVer = priVer + " " + priPatch
except IndexError:
print "Oops!IndexError!"
pass
try:
secPatch = re.findall(r"(?<=Secondary ver:\s{4}\S{8}\s{19})\S+",readout)[0]
secVer = secVer + " " + secPatch
except IndexError:
print "Oops!IndexError!"
pass
def main():
regexCheck()
print "Primary Version = " + priVer
print "Secondary Version = " + secVer
main()
Primary Version = 12.3.4.5 patch1-2
Secondary Version = 12.6.7.8 patch3-4
switch1.1 # show switch@
@
SysName: switch1@
SysLocation: @
SysContact: support@extremenetworks.com, +1 888 257 3000@
System MAC: 00:01:02:03:04:05@
System Type: X440@
@
SysHealth check: Enabled (Normal)@
Recovery Mode: All@
System Watchdog: Enabled@
@
Current Time: Mon Dec 31 00:00:00 2000@
Timezone: [Auto DST Disabled] GMT Offset: 0 minutes, name is UTC.@
Boot Time: Mon Dec 31 00:00:00 2000@
Boot Count: 1@
Next Reboot: None scheduled@
System UpTime: 0 minutes 0 seconds @
@
Current State: OPERATIONAL @
Image Selected: primary @
Image Booted: primary @
Primary ver: 12.3.4.5 @
patch1-2@
Secondary ver: 12.6.7.8 @
@
Config Selected: primary.cfg @
Config Booted: primary.cfg @
@
primary.cfg Created by ExtremeXOS version 15.7.1.4@
123456 bytes saved on Mon Dec 31 00:00:00 2000@
switch1.2 #
>>> d = {}
... prev_key = None
... for line in readout.splitlines():
... try:
... key, value = line.split(':', maxsplit=1)
... except ValueError:
... current_line = line.strip()
... if current_line:
... d[prev_key] += ' {}'.format(current_line)
... else:
... d[key] = value.strip()
... prev_key = key
...
>>> import json; print(json.dumps(d, indent=2))
{
"SysName": "switch1",
"SysLocation": "",
"SysContact": "support@extremenetworks.com, +1 888 257 3000",
"System MAC": "00:01:02:03:04:05",
"System Type": "X440",
"SysHealth check": "Enabled (Normal)",
"Recovery Mode": "All",
"System Watchdog": "Enabled",
"Current Time": "Mon Dec 31 00:00:00 2000",
"Timezone": "[Auto DST Disabled] GMT Offset: 0 minutes, name is UTC.",
"Boot Time": "Mon Dec 31 00:00:00 2000",
"Boot Count": "1",
"Next Reboot": "None scheduled",
"System UpTime": "0 minutes 0 seconds",
"Current State": "OPERATIONAL",
"Image Selected": "primary",
"Image Booted": "primary",
"Primary ver": "12.3.4.5 patch1-2",
"Secondary ver": "12.6.7.8 patch3-4",
"Config Selected": "primary.cfg",
"Config Booted": "primary.cfg"
}
>>> d['Primary ver']
'12.3.4.5 patch1-2'
>>> d['Secondary ver']
'12.6.7.8 patch3-4'
>>> main()
Primary Version = 12.3.4.5 patch1-2
Secondary Version = 12.6.7.8 patch3-4
>>> readout = readout.replace("\n", "\r\n")
>>> main()
Oops!IndexError!
Oops!IndexError!
Primary Version = 12.3.4.5
Secondary Version = 12.6.7.8