Java Regex过于贪婪地捕获组

时间:2016-01-28 14:45:23

标签: java regex

    Node0x7fd34984d728:s1 -> Node0x7fd34984d600:d0;
    Node0x7fd34984d850 [shape=record,shape=Mrecord,label="{Register %vreg13|0x7fd34984d850|{<d0>i32}}"];
    Node0x7fd34984d978 [shape=record,shape=Mrecord,label="{{<s0>0|<s1>1}|CopyFromReg [ORD=1]|0x7fd34984d978|{<d0>i32|<d1>ch}}"];
    Node0x7fd34984d978:s0 -> Node0x7fd3486095f0:d0[color=blue,style=dashed];
    Node0x7fd34984d978:s1 -> Node0x7fd34984d850:d0;
    Node0x7fd34984daa0 [shape=record,shape=Mrecord,label="{Register %vreg14|0x7fd34984daa0|{<d0>i32}}"];

我正在尝试仅使用“ORD”关键字捕获节点,我的简单正则表达式模式是:

Node.+?label=\"\\{\\{(?<SRC><s[0-9]+?>[a-z0-9]+?)\\}|(?<NAME>.+?)\\[ORD=(?<ORD>[0-9]+?)\\]\\|(?<ID>[A-Za-z0-9]{14})|\\{(?<DEST><d[0-9]+?>[a-z0-9]+?)\\}\\}\"\\];

过于贪婪地捕获了错误的群体。

以下代码段被捕获为一个组!

Node0x7fd34984d728:s1 -> Node0x7fd34984d600:d0;
Node0x7fd34984d850 [shape=record,shape=Mrecord,label="{Register %vreg13|0x7fd34984d850|{<d0>i32}}"];
Node0x7fd34984d978 [shape=record,shape=Mrecord,label="{{<s0>0|<s1>1}|CopyFromReg [ORD=1]|0x7fd34984d978|{<d0>i32|<d1>ch}}"];

然而,它必须只捕获:

Node0x7fd34984d978 [shape=record,shape=Mrecord,label="{{<s0>0|<s1>1}|CopyFromReg [ORD=1]|0x7fd34984d978|{<d0>i32|<d1>ch}}"];

因为它是分号

之前唯一的节点具有“ ORD ”关键字

2 个答案:

答案 0 :(得分:1)

我建议不要使用一个怪物图案,而是使用两个简单的图案来提取你想要的东西 首先使用这种模式:

^Node.*?label="{(.*\bORD\b.*)}".*?;

提取&#34;只有Node有&#34; ORD&#34;在Semicolon&#34;之前的关键字 {<s0>0|<s1>1}|CopyFromReg [ORD=1]|0x7fd34984d978|{<d0>i32|<d1>ch}
Demo

然后使用此模式

({.+?}|[^\|]+(?=\[ORD=\d+\])|[^\|]+)

对于您的各种捕获组 - 但它们的编号未命名。
Demo
结果:

  

比赛1   {<s0>0|<s1>1}
  比赛2   CopyFromReg
  比赛3   [ORD=1]
  比赛4   0x7fd34984d978
  比赛5   {<d0>i32|<d1>ch}

答案 1 :(得分:1)

你需要摆脱任何懒惰和点匹配模式,并用否定的字符类替换它们。这样,你就可以防止&#34;溢出&#34;在你的子串之间。

String pattern = "Node[^\\]\\[]*\\[[^\\]\\[]*label=\"\\{\{(?<SRC>[^{}]*)\\}\\|(?<NAME>\\w+)\\s*\\[ORD=(?<OR‌​D>\\d+)\\]\\|(?<ID>[^|]*)\\|\\{(?<DEST>[^{}]*)\\}\\}\"\\];";

请参阅demo