用于匹配可能不存在的组的正则表达式
Regular Expression to match groups that may not exist
我正在尝试从应用程序的日志中捕获一些数据。日志如下所示:
*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE2}, {count=93.0, state=STATE3}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*
如果特定状态的 count 永远为 0,它实际上根本不会出现在日志中,所以我不能保证对象的顺序日志 (唯一的顺序是它们按州名字母顺序排序)
所以,这也是一个潜在的日志:
*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*
我对使用正则表达式有些陌生,我觉得我用得太过了,但这是我试过的。
^[^=\n]*=(?:(?P<STATE1>\d+)(?=\.0,\s+\w+=STATE1))*.*?=(?P<STATE2>\d+)(?=\.0,\s+\w+=STATE2)*.*?=(?P<STATE3>\d+)(?=\.0,\s+\w+=STATE3)
我的想法是寻找“=”,然后向前看,看看这是否是我想要的状态,它可能存在也可能不存在。然后在计数之后跳过所有垃圾,直到我感兴趣的下一个状态(这是我认为有问题的部分)。有时它匹配得太远,会跳过我感兴趣的状态,给我一个不好的值。如果我使用惰性运算符(如上所述),有时它还不够远,并获得日志中我想要的 state 之前的计数。
看看这个方法是否适合你:
正则表达式:(?<=count=)\d+(?:\.\d+)?(?=, state=(STATE\d+))
分组将是您的状态#,完全匹配将是计数值
您可以使用 2 个捕获组来捕获计数和状态。
要捕获例如 STATE1、STATE2、STATE3 和 STATE5,您可以使用带有范围和/或交替的字符 class 指定数字。
{count=(\d+(?:\.\d+)?), state=(STATE(?:[123]|5))}
说明
{count=
字面匹配
(
捕获 组 1
\d+(?:\.\d+)?
匹配 1+ 个带可选小数部分的数字
)
关闭群组
, state=
字面匹配
(
捕获 第 2 组
STATE(?:[123]|5)
匹配 STATE 并指定允许的数字
)}
关闭群组并匹配 }
如果要匹配所有状态和数字:
{count=(\d+(?:\.\d+)?), state=(STATE\d+)}
经过一些实验,这就是我想出的:
此处提供的答案,虽然很好的答案,但相当工作如果您的州名称不以数字结尾(我的不是,我只是更改它们以使问题更易于阅读并从问题中删除业务信息)。
这是一个完全可拼贴的正则表达式,您可以根据需要在其中添加任意数量的匹配项
count=(?P<GROUP_NAME_HERE>\d+(?=\.0, state=STATE_NAME_HERE))?
这可以复制并附加新的状态名称和组名称。
此外,如果任何状态未出现在字符串中,它仍将匹配以下状态。例如:
count=(?P<G1>\d+(?=\.0, state=STATE_ONE))?(?P<G2>\d+(?=\.0, state=STATE_TWO))?(?P<G3>\d+(?=\.0, state=STATE_THREE))?
将在以下字符串中将状态 STATE_ONE
和 STATE_THREE
与命名组 G1
和 G3
匹配,即使缺少 STATE_TWO:
[{count=55.0, state=STATE_ONE}, {count=10.0, state=STATE_THREE}]
我确信这可以改进,但它对我来说已经足够快了,并且使用 11 groups
,regex101 显示 803
步,时间为 ~1ms
这里有一个 regex101 操场:https://regex101.com/r/3a3iQf/1
注意第 1、2、3、4、5、6、7、9 和 11 组是如何匹配的。缺少 8 和 10,以下组仍然匹配。
我正在尝试从应用程序的日志中捕获一些数据。日志如下所示:
*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE2}, {count=93.0, state=STATE3}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*
如果特定状态的 count 永远为 0,它实际上根本不会出现在日志中,所以我不能保证对象的顺序日志 (唯一的顺序是它们按州名字母顺序排序)
所以,这也是一个潜在的日志:
*junk* [{count=240.0, state=STATE1}, {count=1.0, state=STATE4}, {count=1147.0, state=STATE5}, etc. ] *junk*
我对使用正则表达式有些陌生,我觉得我用得太过了,但这是我试过的。
^[^=\n]*=(?:(?P<STATE1>\d+)(?=\.0,\s+\w+=STATE1))*.*?=(?P<STATE2>\d+)(?=\.0,\s+\w+=STATE2)*.*?=(?P<STATE3>\d+)(?=\.0,\s+\w+=STATE3)
我的想法是寻找“=”,然后向前看,看看这是否是我想要的状态,它可能存在也可能不存在。然后在计数之后跳过所有垃圾,直到我感兴趣的下一个状态(这是我认为有问题的部分)。有时它匹配得太远,会跳过我感兴趣的状态,给我一个不好的值。如果我使用惰性运算符(如上所述),有时它还不够远,并获得日志中我想要的 state 之前的计数。
看看这个方法是否适合你:
正则表达式:(?<=count=)\d+(?:\.\d+)?(?=, state=(STATE\d+))
分组将是您的状态#,完全匹配将是计数值
您可以使用 2 个捕获组来捕获计数和状态。
要捕获例如 STATE1、STATE2、STATE3 和 STATE5,您可以使用带有范围和/或交替的字符 class 指定数字。
{count=(\d+(?:\.\d+)?), state=(STATE(?:[123]|5))}
说明
{count=
字面匹配(
捕获 组 1\d+(?:\.\d+)?
匹配 1+ 个带可选小数部分的数字
)
关闭群组, state=
字面匹配(
捕获 第 2 组STATE(?:[123]|5)
匹配 STATE 并指定允许的数字
)}
关闭群组并匹配}
如果要匹配所有状态和数字:
{count=(\d+(?:\.\d+)?), state=(STATE\d+)}
经过一些实验,这就是我想出的:
此处提供的答案,虽然很好的答案,但相当工作如果您的州名称不以数字结尾(我的不是,我只是更改它们以使问题更易于阅读并从问题中删除业务信息)。
这是一个完全可拼贴的正则表达式,您可以根据需要在其中添加任意数量的匹配项
count=(?P<GROUP_NAME_HERE>\d+(?=\.0, state=STATE_NAME_HERE))?
这可以复制并附加新的状态名称和组名称。 此外,如果任何状态未出现在字符串中,它仍将匹配以下状态。例如:
count=(?P<G1>\d+(?=\.0, state=STATE_ONE))?(?P<G2>\d+(?=\.0, state=STATE_TWO))?(?P<G3>\d+(?=\.0, state=STATE_THREE))?
将在以下字符串中将状态 STATE_ONE
和 STATE_THREE
与命名组 G1
和 G3
匹配,即使缺少 STATE_TWO:
[{count=55.0, state=STATE_ONE}, {count=10.0, state=STATE_THREE}]
我确信这可以改进,但它对我来说已经足够快了,并且使用 11 groups
,regex101 显示 803
步,时间为 ~1ms
这里有一个 regex101 操场:https://regex101.com/r/3a3iQf/1
注意第 1、2、3、4、5、6、7、9 和 11 组是如何匹配的。缺少 8 和 10,以下组仍然匹配。