首先:我对正则表达式不强。现在,那就在桌面上。 我正在构建一个使用组和可选组件的正则表达式。我遇到的问题是,我需要在两个不同的区域匹配一定数量,并给它们相同的组名。这似乎不起作用。
所以具体细节。我正在分析来自JVM的垃圾收集日志。 有问题的两行是完整的GC和常规的GC。
我打破了这些以使它们可读。
全线:
229980.058: [Full GC 229980.058:
[CMS: 2796543K->2796543K(2796544K), **13.3050667** secs]
2983863K->2872464K(4067264K),
[CMS Perm : 325367K->325242K(1048576K)], 13.3054416 secs]
[Times: user=13.27 sys=0.03, real=13.31 secs]
常规行:
2.752: [GC 2.752:
[ParNew: 1143680K->4938K(1270720K), **0.0243534** secs]
1143686K->4945K(4067264K), 0.0245283 secs]
[Times: user=0.05 sys=0.02, real=0.03 secs]
如您所见,Full GC将CMS / tenured generation作为第一个字段区域。第二个没有这些,因为它只是常规集合。
为了捕获这些,正确的我已经使“CMS:”和“ParNew:”部分彼此可选。但是,我希望将每个时间作为一个组名称拉出来。 (我放的价值**)
我正在使用这个正则表达式:
\ d +。\ d +:[(Full \ s)?GC \ s \ d +。\ d +:[(CMS:\ s(?< JVM_TenuredGenHeapUsedBeforeGC> \ d +)+ K->(?< JVM_TenuredHeapUsedAfterGC> ; \ d +)K(\ d + K),\ S(小于?JVM_GCTimeTaken> \ d + \ d +)\ ssecs)。? ?(ParNew:???\ S(\ d +)+ K->(小于JVM_NewGenHeapUsedAfterGC> \ d +)K((小于JVM_NewGenHeapSize> \ d +)K),\ S(小于JVM_GCTimeTaken> \ d + \ d +)\ ssecs)?] .. [为简洁而编辑]
简而言之..是否可以在不同的可选匹配上使用相同的组名?他们永远不会在同一条线上,所以我不知道为什么我不能这样做。
使用regexr进行测试似乎也失败了。谢谢!
答案 0 :(得分:3)
我遇到的问题是,我需要在两个不同的区域匹配一定数量,并给它们相同的组名。
我会说这就是问题所在。我没有试过这个,但是我看到了引入命名组的更改列表,而这只是命名一个编号组。所以它无法运作。
给他们不同的名字并使用类似
的内容Objects.firstNonNull(m.group("foo"), m.group("bar"))
如果您确定其中至少有一个非空(否则您将获得NPE)。或者写下你自己的无效接收单行。
答案 1 :(得分:3)
一些小实验表明Java不允许您在正则表达式中定义两次相同的捕获组名称。以下代码生成以下异常:
public class NamedCapturingGroupMain {
public static void main(String[] args) {
Pattern p = Pattern.compile("(?<mygroup>a)|(?<mygroup>b)");
}
}
例外:
Exception in thread "main" java.util.regex.PatternSyntaxException: Named capturing group <mygroup> is already defined near index 24
这里最简单的方法可能是定义两个不同的捕获组名称,如果第一个名称为null,则使用第二个名称。例如,如果您使用“JVM_GCTimeTakenFull”和“JVM_GCTimeTakenPartial”,然后执行以下操作:
String gcTimeTaken = matcher.group("JVM_GCTimeTakenFull");
if (gcTimeTaken == null) {
gcTimeTaken = matcher.group("JVM_GCTimeTakenPartial");
}
答案 2 :(得分:2)
编辑 - 如果Java不允许重复名称,我错过了Java标记(我知道了
它不支持分支重置)你可以这样做,然后测试一个匹配
Full_GC
和CMS
(可让您解释下一组)
无论哪种方式,您只需要一个JVM_GCTimeTaken
组。
# "\\d+\\.\\d+:\\s*\\[(?:(?<Full_GC>Full\\s*GC)|(?<GC>GC))\\s*(?<GC_Val>\\d+\\.\\d+):\\s*\\[(?:(?<CMS>CMS)|(?<ParNew>ParNew)):\\s*(?<HeapUsedBefore>\\d+)K->(?<HeapUsedAfter>\\d+)K\\((?<NewHeapSize>\\d+)K\\),\\s*(?<JVM_GCTimeTaken>\\d+\\.\\d+)\\s*secs\\]"
\d+ \. \d+ : \s*
\[
(?:
(?<Full_GC> Full \s* GC ) # (1)
| (?<GC> GC ) # (2)
)
\s*
(?<GC_Val> \d+ \. \d+ ) # (3)
:
\s*
\[
(?:
(?<CMS> CMS ) # (4)
| (?<ParNew> ParNew ) # (5)
)
: \s*
(?<HeapUsedBefore> \d+ ) # (6)
K->
(?<HeapUsedAfter> \d+ ) # (7)
K
\(
(?<NewHeapSize> \d+ ) # (8)
K
\)
, \s*
(?<JVM_GCTimeTaken> \d+ \. \d+ ) # (9)
\s*
secs
\]