我有一个要解析的日志文件。它是使用正则表达式在方括号之间和“确定:”之后获取值。 问题是我不知道该模式发生了多少次,我也不能说每个代码多长时间。因此,我只能依靠它被“ [OK:”和“]”包围的事实。
到目前为止,我试图在此使用此模式作为正则表达式:
String ok_pattern = "(.*itId=<)(.{1,10})(>.*)(\\[OK:)(.{4,27})(].*)";
Pattern p_ok = Pattern.compile(ok_pattern);
String testString = "RANDOMTEXT itId=<1232> Code < [OK:AZ1000105] [OK:10000006] [OK:F1000000007] > RANDOMTEXT";
Matcher m = p_ok.matcher(testString);
if(m.find()) {
System.out.println(m.group(5));
}
但这仅适用于只有一个“ [OK:...]”的情况。 在第5组比赛之后,我使用“ *”和“ +”进行了测试,但我未能成功。 我该如何重复执行并仍然捕获所有结果?
我的目标是使用正则表达式在“ OK:”之后提取itemId和(char-)number组合。因此,在此示例中,我想获取“ 1232”(ItemID)和“ AZ1000105”,“ 10000006”,“ F1000000007”。
感谢您的帮助!
答案 0 :(得分:2)
您的基本设置是正确的,但是您的模式有些不理想。尝试使用以下正则表达式模式:
(?<=\[OK:)[^\]]+|(?<=itId=<)[^>]+
这仍然使用回溯,但仅断言[OK:
之前。然后,它甚至不使用捕获组就匹配不是右方括号的任意数量的字符。这对应于您要查找的内容。交替右边的部分与itId
值匹配。
String ok_pattern = "(?<=\\[OK:)[^\\]]+|(?<=itId=<)[^>]+";
Pattern p_ok = Pattern.compile(ok_pattern);
String testString = "RANDOMTEXT itId=<1232> Code < [OK:AZ1000105] [OK:10000006] [OK:F1000000007] > RANDOMTEXT";
Matcher m = p_ok.matcher(testString);
while (m.find()) {
System.out.println(m.group(0));
}
1232
AZ1000105
10000006
F1000000007
答案 1 :(得分:0)
如果要捕获itId=<1232>
中的数字,然后依次捕获OK:
之后的数字,则可以使用\G
锚点来声明位置上一场比赛的结束。
匹配第一个捕获组中的itId
位数字和第二个捕获组中的OK:
值:
itId=<(\d+)> Code < |\G(?!^)\[OK:([A-Z0-9]+)\]\s*
在Java中:
String ok_pattern = "itId=<(\\d+)> Code < |\\G(?!^)\\[OK:([A-Z0-9]+)\\]\\s*";
说明
itId=<(\d+)> Code <
匹配第一部分并捕获第1组中的1个以上数字|
或\G(?!^)
上一场比赛的结束,而不是开始\[OK:([A-Z0-9]+)\]\s*
匹配[OK:
,然后在组2中捕获您的值并匹配]
,后跟0+个空格字符请注意,如果要匹配多个([A-Z0-9]+)
,还可以使用否定字符类来匹配不匹配方括号([^]]+)
例如,您可以检查组是否存在:
String ok_pattern = "itId=<(\\d+)> Code < |\\G(?!^)\\[OK:([^]]+)\\]\\s*";
Pattern p_ok = Pattern.compile(ok_pattern);
String testString = "RANDOMTEXT itId=<1232> Code < [OK:AZ1000105] [OK:10000006] [OK:F1000000007] > RANDOMTEXT";
Matcher m = p_ok.matcher(testString);
while(m.find()) {
if (null != m.group(1)) {
System.out.println("itId: " + m.group(1));
}
if (null != m.group(2)) {
System.out.println("Ok code: " + m.group(2));
}
}