Java 正则表达式 : Why is in my sample not the longest resp. 左匹配已被采用?

标签 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 拆分为两个正则表达式,然后首先使用 <> 将输入应用到该表达式。如果这不匹配,请尝试另一个不带 <> 的选项。但我很好奇这如何仅使用一个正则表达式。

最佳答案

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

将其改为非贪婪的:

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

RegEx Demo

关于Java 正则表达式 : Why is in my sample not the longest resp. 左匹配已被采用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33376207/

相关文章:

java - 在 Java 中继承流利的 setter

c# - 如何使用正则表达式替换匹配的周围组?

javascript - 如何使用 JavaScript 获取 div 中的字符数(忽略空格)?

用于匹配 3 个字母和 1-2 个数字的正则表达式

javascript - 匹配捕获组或在 Javascript 正则表达式中丢失时匹配失败

java - 同步每分钟节拍/发送量化消息

java - 如果在 JSP 中选中复选框,则显示/隐藏内容

java - java中的拆分和替换方法

c++ - 正则表达式解析器

python - 用于匹配大写字母和数字的正则表达式