Regex 查找后断言和可选子字符串存在问题

Regex 查找后断言和可选子字符串存在问题,regex,lookahead,lookbehind,Regex,Lookahead,Lookbehind,我正试图编写一些正则表达式来解析Hyperic HQ生成的警报中的信息。警报以电子邮件的形式出现,主题行如下: "[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed" 长话短说,我需要能够始终如一地获取“ApacheWeb服务器”部分,而不管主机名可能不存在。我知道主机名总是以“myserver.net”结尾 我的正则表达式是: /Resource:

我正试图编写一些正则表达式来解析Hyperic HQ生成的警报中的信息。警报以电子邮件的形式出现,主题行如下:

"[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed"
长话短说,我需要能够始终如一地获取“ApacheWeb服务器”部分,而不管主机名可能不存在。我知道主机名总是以“myserver.net”结尾

我的正则表达式是:

/Resource:\s.*(?<=mydomain.net)?\s(.*)\s(?=State)/

这似乎适用于我编写的测试

/Resource:\s(?:.*myserver.net)?(?<PartIWant>.*)\s(?:State)/

这似乎适用于我编写的测试

/Resource:\s(?:.*myserver.net)?(?<PartIWant>.*)\s(?:State)/

这是一个反模式的例子,我称之为提前求助于环顾。您知道您要查找的字符串前面是
foo
,后面是
bar
,并且您知道正则表达式中有lookbehinds和lookaheads,因此很明显您应该使用:

(?<=foo).*(?=bar)
您的正则表达式中还有一个明显的错误:lookback上的
量词:

(?<=mydomain.net)?

(?这是一个反模式的例子,我称之为提前求助于Lookaround。你知道你要查找的字符串前面是
foo
,后面是
bar
,你知道正则表达式有lookbehinds和lookaheads,所以很明显你应该使用:

(?<=foo).*(?=bar)
您的正则表达式中还有一个明显的错误:lookback上的
量词:

(?<=mydomain.net)?

(?有时,事情可以简单地完成。在您最喜欢的语言中,在“myserver.net”上进行拆分,然后在第一个元素的“State:”上进行拆分。例如在Python中

>>> s="""[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed"""
>>> s.split("myserver.net")[-1].split("State:")[0]
' Apache Web Server '

有时候,事情可以做得很简单。在您最喜欢的语言中,在“myserver.net”上进行拆分,然后在第一个元素的“State:”上进行拆分。例如在Python中

>>> s="""[HQ] !!! - Alert: My Demo Website Alert Resource: demo.myserver.net Apache Web Server State: fixed"""
>>> s.split("myserver.net")[-1].split("State:")[0]
' Apache Web Server '

下载expresso,将所有可能的字符串放在测试数据中,然后运行此测试,看看它是否与+1正确匹配。您可能也不需要对“State”使用前瞻。@Alan,甚至没有注意到,您是对的,它不需要there@HappySpaceInvader,您是否更改了“myserver.net”你的域名的一部分?因为我已经用几个不同的字符串对它进行了测试,它在命名的捕获组“PartIWant”中返回了正确的匹配项。谢谢-我的正则表达式技能已经相当生疏,我已经忘记了简单的非捕获组(?:foo)。删除多余的前瞻和命名捕获(这在我的特定情况下无论如何都不起作用),我找到了以下工作:/Resource:\s(?:.*.myserver.net)?(.*)State/Download expresso,将所有可能的字符串放入测试数据中,然后运行此测试,查看它是否正确匹配+1。您可能不需要对“State”使用前瞻也可以。@Alan,甚至没有注意到,你是对的,不需要这样做there@HappySpaceInvader,您是否将“myserver.net”部分更改为您的域名?因为我已经用几个不同的字符串对其进行了测试,并且它在命名的捕获组“PartIWant”中返回了正确的匹配项谢谢-我的正则表达式技能已经相当生疏,我已经忘记了简单的非捕获组(?:foo)。删除多余的前瞻和命名捕获(在我的特定情况下无论如何都不起作用),我发现了以下工作:/Resource:\s(?:.myserver.net)?(*)\sState/Ah,但我仅限于regex-在我从原始帖子中发布的背景故事的长版本中。很抱歉没有说清楚。啊,但我仅限于regex-在我从原始帖子中发布的背景故事的长版本中。很抱歉没有说清楚。这不是我提出的问题。我正在寻找对于前面是“foo”和“bar”,后面是“japh”的字符串,…其中“bar”可能存在也可能不存在,但如果存在,我不想捕获它。通过“foo”和“bar”,我假定您的意思是
资源:
和主机名,以及“japh”,
状态:
;这没关系。关键是你不需要环顾四周来匹配这些东西,只要“直接”匹配就行了并使用捕获组来提取您感兴趣的部分。如果不允许您使用捕获组,则您必须在lookarounds方面发挥创意,但幸运的是,情况并非如此。这不是我所提出的问题。我正在寻找一个前面有“foo”和“bar”,后面有“japh”的字符串,其中“bar”可能存在,也可能不存在,但如果它存在,我不想捕获它。通过“foo”和“bar”,我假定您的意思是
资源:
和主机名,通过“japh”
声明:
;这不重要。重点是,您不需要环视来匹配任何这些内容,只要“直接”匹配它们就可以了并使用捕获组提取您感兴趣的部分。如果不允许您使用捕获组,则您必须在环顾四周时发挥创意,但幸运的是,情况并非如此。