正则表达式匹配模式一,跳过换行符和字符,直到出现模式二。

3
我需要一个正则表达式,用于多行跳过直到模式匹配,并且我没有看到已经涵盖它的内容。
Name of person 
 Jack
 Nichol 
 Age 42
 .....
 .....
 ....
Name of person
 Andrew
 Jason
 Age 54
...

我该如何匹配 - 类似于 (Name.*(?:(\n)+).*(?:Age))

考虑下面的代码 -

interface TenGigE0/0/0/7



shutdown

!

interface TenGigE0/0/0/8



 bundle id 221 mode active

 lacp period short

 lacp period short receive 100

 lacp period short transmit 100

 carrier-delay up 100 down 100

 load-interval 30

 frequency synchronization

 !

 transceiver permit pid all

!

interface TenGigE0/0/0/9



 mtu 9216

 frequency synchronization

 !

 transceiver permit pid all

!

interface TenGigE0/0/0/10



 bundle id 237 mode active

 lacp period short

 lacp period short receive 100

 lacp period short transmit 100

 carrier-delay up 120000 down 150

 load-interval 30

 frequency synchronization

我该如何匹配所有的Tengigex/x/x/x接口和对应的carrier-delay延迟行?就像下面这样 -
[interface TenGigE0/0/0/8,carrier-delay up 100 down 100] [interface TenGigE0/0/0/10,carrier-delay up 120000 down 150] ......等等。

请问您需要匹配什么内容?使用哪种正则表达式语法?请参考:https://regex101.com/r/hS2uJ3/1 或 https://regex101.com/r/hS2uJ3/2。 - Wiktor Stribiżew
姓名 + 年龄 - 所有出现的地方 - user6259926
数据是虚拟的,但是我的意思是我想匹配 x 然后跳过所有的换行和字符直到 y。重复进行。 - user6259926
好的,请更新问题并解释期望的输出以及“转义换行符和字符”的含义。 - Wiktor Stribiżew
更新了示例输入和期望输出。 - user6259926
2个回答

2
为了匹配包含 tengigecarrier-delay 的最接近的行之间的内容,需要使用 温和贪婪量词(或展开版本)。
(?sim)^([^\n]*TenGigE[^\n]*)(?:(?!TenGigE|carrier-delay).)*([^\n]*carrier-dela‌​y[^\n]*)

查看正则表达式演示

查看Python演示

import re
p = re.compile(r'^([^\n]*TenGigE[^\n]*)(?:(?!TenGigE|carrier-delay).)*([^\n]*carrier-delay[^\n]*)', re.DOTALL | re.M | re.I)
test_str = "interface TenGigE0/0/0/8\n bundle id 221 mode active\n lacp period short\n lacp period short receive 100\n lacp period short transmit 100\n carrier-delay up 100 down 100\n\ninterface TenGigE0/0/0/7\n\n\n\nshutdown\n\n!\n\ninterface TenGigE0/0/0/8\n\n\n\n bundle id 221 mode active\n\n lacp period short\n\n lacp period short receive 100\n\n lacp period short transmit 100\n\n carrier-delay up 100 down 100\n\n load-interval 30\n\n frequency synchronization\n\n !\n\n transceiver permit pid all\n\n!\n\ninterface TenGigE0/0/0/9\n\n\n\n mtu 9216\n\n frequency synchronization\n\n !\n\n transceiver permit pid all\n\n!\n\ninterface TenGigE0/0/0/10\n\n\n\n bundle id 237 mode active\n\n lacp period short\n\n lacp period short receive 100\n\n lacp period short transmit 100\n\n carrier-delay up 120000 down 150\n\n load-interval 30\n\n frequency synchronization"
print(p.findall(test_str))
# => [('interface TenGigE0/0/0/8', 'carrier-delay up 100 down 100'), ('interface TenGigE0/0/0/8', 'carrier-delay up 100 down 100'), ('interface TenGigE0/0/0/10', 'carrier-delay up 120000 down 150')]

更新

一种非常强大的正则表达式,基于展开循环技术(展开调节贪婪标记),用于提取相同文本:

(?sim)^([^\n]*TenGigE[^\n]*\n)[^T\n]*(?:T(?!enGigE)[^T\n]*|\n(?! carrier-delay)[^T\n]*)*(\n carrier-delay[^\n]*)

请看正则表达式演示

请检查此内容,并告诉我是否需要捕获块内的其他内容。 - Wiktor Stribiżew
谢谢,接近了。但是需要仅列出以下内容 - [接口TenGigE0/0/0/8,载波延迟上行100下行100],而不是它们之间的任何其他东西,如LACP或描述等。已接受答案,但如果能再精细一些就更好了。 - user6259926
我已经更新了答案,包括正则表达式和代码。很高兴它对你有用。如果我的回答对你有帮助,请考虑点赞(请参阅如何在Stack Overflow上点赞?)。 - Wiktor Stribiżew
谢谢。我接受了另一个答案并点赞了这个。 - user6259926
你的演示需要超过200,000步才能成功! - Jan
然后可以使用 (?sim)^([^\n]*TenGigE[^\n]*)(?:(?!TenGigE|carrier-delay).)*([^\n]*carrier-delay[^\n]*) 来将其缩小 10 倍。 - Wiktor Stribiżew

0
你可以想出:
(?:^(interface\ TenGigE
(?:\d+/?){4}))
(?:(?!(?:carrier-delay|interface))[\s\S])+
(?P<carrier>carrier-delay\ .+)

Python 中,这将是:

import re
rx = re.compile("""
(?:^(interface\ TenGigE
(?:\d+/?){4}))
(?:(?!(?:carrier-delay|interface))[\s\S])+
(?P<carrier>carrier-delay\ .+)""", re.VERBOSE|re.MULTILINE)
matches = rx.findall(string)

与@Wiktor的答案相比(需要> 200k步骤),这个只需要约3k步骤,参见regex101.com的演示(在此之前感谢他指出不准确之处)。

这里不是重点\G。重点是你自己在使用温和的贪婪标记。这里不需要使用正则表达式模块。 - Wiktor Stribiżew
@WiktorStribiżew:没错,已更新答案。我开始使用\G(脑海中有另一个解决方案)。但是,为什么需要超过200,000步才能成功呢? - Jan
1
我只有20K,因为OP没有确认这些行应该以interfacecarrier-delay开头。任务是找到包含它们的行。我可以通过添加锚点或/和展开模式来进一步提高性能,当然。 - Wiktor Stribiżew
@WiktorStribiżew:该死,你抓住我了 :) - Jan
:-) 正则表达式确实让每个人都感到困扰。2个自白。我提供的输入数据被修剪了一些-必须编辑关于接口描述的私人信息。如果只匹配后跟载波延迟的tenGig,那么范围就很大。例如。它找到一个<teng...shutdown...tengig...carrier-delay> 从而给出不准确的结果。 我已经进一步限制了它。 <tengig..description..carrier-delay> 将正则表达式粘贴记录。(tengigE.(?:\r|\n)\s.des.?)\n\n(?:.|\n)+?(Car.*?)\n gmi - user6259926
还有一件事情想要补充 - 尽管在regex101上它可以完美地工作,但是当我将文件读入缓冲区并在其上运行re.findall时,正则表达式在Windows上却无法工作。因此,在Windows上操作时,请将文件读入缓冲区并将其输出到屏幕。然后将该输出粘贴到regex101中并构建您的正则表达式。 - user6259926

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接