Java Regex:为什么我的样本不是最长的。左边比赛?

时间:2015-10-27 18:50:20

标签: java regex regex-greedy

测试用例

Pattern P1 = Pattern.compile(".*(<\\{([0-9A-Za-z_]+)\\}>).*");
Pattern P2 = Pattern.compile(".*(<\\{([0-9A-Za-z_]+)\\}>|\\{([0-9A-Za-z_]+)\\}).*");

String text = "a <{xyz}> b";

Matcher m = P1.matcher(text);
m.matches();
String g1 = m.group(1);
System.out.println(g1);

m = P2.matcher(text);
m.matches();
g1 = m.group(1);
System.out.println(g1);

输出

<{xyz}>
{xyz}

问题

我原以为,对于P2,输出也是<{xyz}>,因为

  • 这是OR中的第一条规则
  • 匹配<{xyz}>超过{xyz}
猜猜我错过了一些东西,却无法弄清楚是什么。所以我的目标是,对于具有OR条件的模式,结果为<{xyz}>

口头目标如下: 匹配<{...}>{...}内的某些内容,但如果输入为<>,则将其作为首选内容。

目前我想到的唯一解决方案是将P2拆分为两个正则表达式,然后首先将输入应用于<>的那个,如果不匹配则尝试另一个没有<>的解决方案。 1}}。但我很好奇这只能用一个正则表达式来实现。

1 个答案:

答案 0 :(得分:2)

在允许.*中的模式之前,第2个正则表达式开头的问题是贪婪的(...)匹配最长匹配。

将其改为非贪婪的人:

.*?(<\{([0-9A-Za-z_]+)\}>|\{([0-9A-Za-z_]+)\}).*

RegEx Demo