在正则表达式中将两组合二为一

Combining two groups into one in regex

我正在解析 IBM JVM 线程转储以提取各种信息。在当前上下文中,线程正在等待的锁 ID,以及拥有该锁的线程的 ID。锁 ID 在所有转储中都是一致的,它采用十六进制值 0x000000000B0D9A20 的形式。但是持有锁的线程的 id 采用不同的值,例如与锁 id 相同形式的十六进制 id 或 <unknown><unowned> 之类的东西。我发现很难提取锁所有者的 ID。

IBM 线程转储使用三个子句指定锁定信息(如您在第一个屏幕截图中所见):

  1. Waiting on...
  2. Blocked on...
  3. Parked on...

我正在对正则表达式中的这些子句执行 OR 运算。

我写了一个通用方法接受

  1. 线程转储行
  2. 要应用的正则表达式
  3. 列表中 return 的组数

例如调用 method1(threadDumpLine,regex,2) 将在 threadDumpLine 和 return 列表 [group1,group2] 上应用 regex,其中 group1 是第一组在 group2 是第二个时捕获。

第一组需要是我能够捕获的锁 ID,但第二组可以是十六进制 ID 或 <unknown><unowned>。我能够将锁所有者的 ID 作为第二组捕获,但是当它是 <unowned><unknown> 时,结果是第三组:

(以上 regex101

发生这种情况是因为我定义了两个单独的组来捕获锁所有者的 ID 和 <text>。所以我尝试将两者合二为一:

(以上 regex101

如何以最少的步骤更改正则表达式以按照上面指定的方式进行捕获?

您可以使用这个基于否定的正则表达式来获得正确的捕获组 #2:

(?:Blocked on|Parked on|Waiting on):[^@]*@(0x[0-9A-F]+) Owned by:[^<\n]*(0x[0-9]+|[^>\n]+)

RegEx Demo

这将给出以下匹配数据:

MATCH 1
1.  [69-87] `0x000000000B0D9A20`
2.  [185-186]   `)`

MATCH 2
1.  [288-306]   `0x000000000296F1E8`
2.  [317-325]   `<unknown`

MATCH 3
1.  [466-484]   `0x0000000030A0C590`
2.  [495-503]   `<unowned`

试试这个:

(?:Blocked on|Parked on|Waiting on):[^@]*@(0x[0-9A-F]+) Owned by:[^<\n]*?(0x[0-9A-F]+|<.*?>)

输出:

MATCH 1
    > 1.    [69-87]     `0x000000000B0D9A20`
    > 2.    [130-148]   `0x00000000846F4900` 
MATCH 2
    > 1.    [288-306]   `0x000000000296F1E8`
    > 2.    [317-326]   `<unknown>` 
MATCH 3
    > 1.    [466-484]   `0x0000000030A0C590`
    > 2.    [495-504]   `<unowned>`

demo