跨多行的 Python 正则表达式

python regular expression across multiple lines

提问人:user225882 提问时间:12/9/2009 最后编辑:nobodyuser225882 更新时间:8/26/2015 访问量:23061

问:

我正在使用 python 和 pexpect 从一些思科设备收集一些信息,并且在 RE 提取讨厌的小项目方面取得了很大成功。恐怕我已经碰壁了。一些交换机堆叠在一起,我已经在脚本中识别了这一点,并使用了一个单独的例程来解析数据。如果交换机是堆叠的,您会看到以下内容(从 sho ver 输出中提取)

Top Assembly Part Number        : 800-25858-06
Top Assembly Revision Number    : A0
Version ID                      : V08
CLEI Code Number                : COMDE10BRA
Hardware Board Revision Number  : 0x01


Switch   Ports  Model              SW Version              SW Image
------   -----  -----              ----------              ----------
*    1   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M  
     2   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     3   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     4   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M


Switch 02 
---------
Switch Uptime                   : 11 weeks, 2 days, 16 hours, 27 minutes
Base ethernet MAC Address       : 00:26:52:96:2A:80
Motherboard assembly number     : 73-9675-15

当我遇到这种情况时,我需要提取 4 表中每个开关的开关编号和型号(sw 可以忽略,但可以有 1 到 9 个开关)这是多行的东西让我,因为我对其余的都没问题。有什么想法吗?

好的,抱歉。我的正则表达式只是开始查看最后一组 - 直到..那我就干不了了,不知道该去哪里!
-{10]\s-{10}(.+)开关

模型会改变,开关的数量也会改变,我需要捕获此示例中的 4 条线,它们是

*    1   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M  
     2   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     3   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     4   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M

但每个开关可能是不同的型号,可能介于 1 到 9 之间。对于这个例子,理想情况下,我想得到

*,1,WS-C3750-48P
,2,WS-C3750-48P
,3,WS-C3750-48P
,4,WS-C3750-48P  

(星号表示主控)
但是得到这些台词会让我走上正轨

Python 正则表达式

评论

2赞 Tom 12/9/2009
你发布你尝试过的当前正则表达式代码怎么样......我不确定我是否完全理解你想得到什么。

答:

8赞 YOU 12/9/2009 #1
x="""Top Assembly Part Number        : 800-25858-06
Top Assembly Revision Number    : A0
Version ID                      : V08
CLEI Code Number                : COMDE10BRA
Hardware Board Revision Number  : 0x01


Switch   Ports  Model              SW Version              SW Image
------   -----  -----              ----------              ----------
*    1   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     2   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     3   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M
     4   52     WS-C3750-48P       12.2(35)SE5             C3750-IPBASE-M


Switch 02
---------
Switch Uptime                   : 11 weeks, 2 days, 16 hours, 27 minutes
Base ethernet MAC Address       : 00:26:52:96:2A:80
Motherboard assembly number     : 73-9675-15"""

>>> import re
>>> re.findall("^\*?\s*(\d)\s*\d+\s*([A-Z\d-]+)",x,re.MULTILINE)
[('1', 'WS-C3750-48P'), ('2', 'WS-C3750-48P'), ('3', 'WS-C3750-48P'), ('4', 'WS-C3750-48P')]

更新:因为 OP 编辑了问题,感谢 Tom 指出 +

>>> re.findall("^(\*?)\s+(\d)\s+\d+\s+([A-Z\d-]+)",x,re.MULTILINE)
[('*', '1', 'WS-C3750-48P'), ('', '2', 'WS-C3750-48P'), ('', '3', 'WS-C3750-48P'), ('', '4', 'WS-C3750-48P')]
>>>

评论

0赞 Tom 12/9/2009
+1,因为我认为你在快速回答问题方面做得很好:-)。但要清理它......我会使用 \s+ 而不是 \s*。另外,重新。在这种情况下,MULTILINE 没有任何重要作用。我相信您的解决方案可以在没有它的情况下工作:-)。
0赞 Alex Martelli 12/9/2009
@Tom,好吧,你需要多行 IF 来匹配行首,正如我在回答中详细阐述的那样——我只是不确定是否真的有必要与行首同步,这取决于如何识别“模型”。^
0赞 user225882 12/9/2009
嗯,你上面做的事情看起来不错,但你只是在解析表格。您正在使用的字符串位于一大堆其他文本(请参阅原始帖子)的中间,表格位于中间。我的数据上面和下面可能有 50 行
0赞 user225882 12/9/2009
顺便说一句,模型将始终以 WS- 开头
0赞 YOU 12/9/2009
好的,我不确定它总是以 WS- 开头,要更新它。
17赞 Alex Martelli 12/9/2009 #2

要匹配任何字符(包括换行符),请使用 re 编译 RE。DOTALL (请记住,如果您有多个选项,请在它们之间使用 bit-or 运算符,以便将它们组合在一起)。.|

在这种情况下,我不确定你是否真的需要这个——为什么不像这样

re.findall(r'(\d+)\s+\d+\s+(WS-\S+)')

例如,假设您识别“模型”的方式是它以 ?一个结果和下一个结果之间会有换行符,这一事实在这里不是问题。您能确切地解释一下您是如何识别“模型”的,以及为什么“多线”是一个问题吗?也许你想要 re。MULTILINE 在每个行首进行匹配,通过对行首的一些参考来获取您的数据......?WS-findall^

评论

1赞 Tom 12/9/2009
亚历克斯,再一次,你打败了我:-)。做多行正则表达式的关键实际上是 re。DOTALL(这很令人困惑,因为你会认为它是 re。多行)。但是,正如他指出的那样,在这种情况下您不需要它,因为您要提取的数据位于自己的行上:-)。另外,我喜欢 alex 使用 \s+,表示 1 个或多个空格字符。另外,我可能会添加一件事......我通常喜欢给我的小组命名:(?P<model>WS-\S+)。
0赞 user225882 12/9/2009
嗯,你可能就在那里 - 会尝试并报告,但由于我是英国人,所以明天就要报告了。非常感谢您抽出宝贵时间接受采访