【发布时间】:2017-09-13 20:16:01
【问题描述】:
我一直在互联网上四处奔波,试图找出如何构建正则表达式来以我需要的方式捕获文本;所以我看到了一些 StackOverflow 问题,但没有一个能表达我想要的,但如果你已经在这里看到了与我的问题类似的东西,请随意指向那篇文章......
我尝试使用递归,但似乎我还不够好,无法让某些东西发挥作用
一些注意事项:
1) 我不能使用解析程序,因为将使用这些数据的程序将使用正则表达式来捕获它,而这个程序是一个“通用”程序,实际上它正在捕获任何需要的数据,我唯一需要做的就是给出正确的正则表达式来获取它需要的信息,而且我需要尽可能地保持它的一致性,所以我不能使用第三方或外部程序。
2) 对 'key': 'value' 可能会有所不同,它们的对数并不总是相同......这就是我认为的困难所在。
3) 将使用此正则表达式的程序是在 Python 2.7.3 中创建的: 这个程序是如何工作的: 它使用一个 Json 配置文件,我可以在其中设置要运行的命令,该命令将为我提供所需的数据,然后我指定一个正则表达式来教程序需要捕获什么以及如何处理它,即:如何处理被捕获的组......所以这就是我不能使用解析器的原因。 该程序使用结构将配置的收集器(使用正则表达式)运行到远程主机并收集所有数据...
4) 程序用于收集数据以将它们发布到网络服务器并获取指标和其他内容,例如图表和监控警报等
我已经能够捕获我计划捕获的几乎所有数据,但是当我试图为此创建一个收集器时,我被卡住了..
以下数据重复如下,但服务器名称不同,当然值也会改变:
Server: Omega-X
celery.queue_length: {'transfer_data': '0', 'factor_a': '0', 'slow': '0', 'factor_b': '0', 'score_retry': '0', 'damage_factor_c': '0', 'voice_ud': '0', 'alarm_factors_bl': '0', 'telemetry_x': '0', 'endstream': '0', 'celery': '0', 'awl': '0', 'prs': '0', 'score': '0', 'feature_factors_xf': '0', 'feature_factors_dc': '0'}
Server: Alfa-X
celery.queue_length: {'transfer_data': '0', 'factor_a': '0', 'slow': '0', 'factor_b': '0', 'score_retry': '0', 'damage_factor_c': '0', 'voice_ud': '0', 'alarm_factors_bl': '0', 'telemetry_x': '0', 'endstream': '0', 'celery': '0', 'awl': '0', 'prs': '0', 'score': '0', 'feature_factors_xf': '0', 'feature_factors_dc': '0'}
我想如何捕捉它:
Server: Omega-X
transfer_data: 0
factor_a: 0
slow: 0
factor_b: 0
score_retry: 0
damage_factor_c: 0
voice_ud: 0
alarm_factors_bl: 0
telemetry_x: 0
endstream: 0
celery: 0
awl: 0
trx: 0
points: 0
feature_factors_xf: 0
feature_factors_dc: 0
Server: Alfa-X
transfer_data: 0
factor_a: 0
slow: 0
factor_b: 0
score_retry: 0
damage_factor_c: 0
voice_ud: 0
alarm_factors_bl: 0
telemetry_x: 0
endstream: 0
celery: 0
awl: 0
trx: 0
points: 0
feature_factors_xf: 0
feature_factors_dc: 0
如果显示一个唯一的服务器,那么并不难,使用下面的正则表达式我可以捕获所有(服务器名称除外):
'([a-z_]+)':\s'(\d+)'
这个正则表达式将只给出第二部分,即变量和值的列表,而不是服务器名称......所以如果我在相同的输出上获得几个具有相同数据的服务器,那么将无法从值来自哪个服务器...
如果我尝试添加对服务器名称的支持: 我尝试了以下正则表达式,它可以工作,但只能捕获服务器名称和第一对参数:
Server:\s([a-zA-Z0-9-]+)\s*celery\.queue_length:\s.('([a-z_]+)':\s'(\d+)')*
我尝试了多种递归功能,但未能实现我想要的。
谁能给我指出正确的方向...?
谢谢。
【问题讨论】:
-
您的第一个模式有效,因为它一次匹配每个键/值对。听起来您现在要做的是一次性处理整个集合,只需一个正则表达式模式。让你的程序像这样捕获任意数量的组可能是不可能的(但如果数量相同,那也不会那么糟糕,正如你上面提到的那样)。与其专注于捕获键/值数据,您可以通过格式化操作(例如匹配
celery\.queue_length: \{|,并替换为\n)来解决问题吗?见:regex101.com/r/rzmJgj/1 -
您好 CAustin,感谢您的回复。它可能很有用,但仍然需要像你提到的那样进行一些清洁。睡觉后,我开始想你和其他人可能会提到,仅使用正则表达式几乎不可能实现,因为我也需要捕获组......
-
我不得不承认我需要在这里违反自己的规则,因为我想要的程序使用正则表达式很难实现。我的意思是;我的程序需要有组才能收集数据,所以在这种情况下使用正则表达式它会给我n个我可能无法正确处理的组......所以可能需要一个预解析程序...
标签: python regex regex-recursion