当前位置: 首页 > 知识库问答 >
问题:

Java正则表达式匹配贪婪数据(可选后缀除外)

艾骏喆
2023-03-14

给定一个字符串

Prefix without commas, remainder with optional suffix (optional suffix)

在一次过程中匹配和提取字符串的3个部分的最佳Java正则表达式是什么?

  1. 第一个逗号之前的前缀
  2. 左括号内的剩余部分
  3. 括号内的后缀

对于上面的示例,3个组(在引号内)将是

  1. “不带逗号的前缀”
  2. “带可选后缀的余数”
  3. “(可选后缀)”

字符串的所有3个部分都是可变长度的。余数部分本身可以包含逗号和括号,可选后缀可以以空格开始,也可以不以空格开始,然后是左括号,后面是零个或多个字符,后面是右括号,后面是可选空格,后面是行尾。

试着像

([^,]*),(.*)(\s*\(.*\))?

只产生第1组和第2组,将第3组置于第2组的末尾。

共有3个答案

霍弘厚
2023-03-14

您可以使用以下正则表达式:

"^([^,]*),([^()]*)(\\s*\\(.*\\))?$"

正则表达式匹配:

  • ^-字符串的开头
  • ([^,]*)-(第1组)0个或更多字符,而不是
  • -文字
  • ([^()]*)-(第2组)0个或更多字符,而不是
  • (\\s*\\(.\\) -(组3)可选组(由于量词表示前面子模式出现1次或0次):
    • \\s*-0或更多空白
    • \\(.\\)-文字然后尽可能多的字符,而不是换行符,直到最后一个

    查看IDEONE演示

    String str = "String prefix without commas, variable length remainder with optional suffix (optional suffix)";
    Pattern ptrn = Pattern.compile("^([^,]*),([^()]*)(\\s*\\(.*\\))?$");
    Matcher matcher = ptrn.matcher(str);
    while (matcher.find()) {
        System.out.println("First group: " + matcher.group(1)
                      + "\nSecond group: " + matcher.group(1) 
                      + (matcher.group(3) != null ? 
                           "\nThrid group: " + matcher.group(3) : ""));
    

洪弘壮
2023-03-14

以下正则表达式:

^([^,]*),(.*?)(?:\(([^()]*)\))?\s*$

在组2中使用惰性量词,以确保如果有括号,则组3将匹配。另一方面,组3不允许嵌套的paren,以强制仅在字符串的最后一组paren中进行匹配。

代码:

String text = "String prefix without commas, variable length ())(remainde()r with )optional (suffix (optional suffix)";
Pattern regex = Pattern.compile("^([^,]*),(.*?)(?:[(]([^()]*)[)])?\\s*$");
Matcher m = regex.matcher(text);
if (m.find()) {
    System.out.println("1: " + m.group(1));
    System.out.println("2: " + m.group(2));
    System.out.println("3: " + m.group(3));
}

输出:

1: String prefix without commas
2:  variable length ())(remainde()r with )optional (suffix 
3: optional suffix

演示

劳法
2023-03-14
([^,]*),(.*)(\s*\(.*\))?

失败的原因是正则表达式已经成功地执行了([^,]*),(.*),并且不需要检查(回溯)其余部分。

要使其正常工作,请按以下方式更改它(可能有几个选项),这些选项要么不匹配最后一个括号,要么将匹配最后一个括号:

^([^,]*),(.*[^\) ]\s*$) | ([^,]*),(.*)(\s*\(.*\))\s*$

结果($1$3$2$4应合并,$1$2,如果没有可选前缀):

3: Prefix without commas
4:  remainder with optional suffix 
5: (optional suffix)

这里我假设您的可选后缀可以出现多次。阅读问题的另一种方式是希望中间部分重复,即$3包含在$2中。您可以按如下方式执行此操作:

^([^,]*),(.*(?:[^\) ]\s*$ | (\s*\(.*\)\s*$)))

结果:

1: Prefix without commas
2:  remainder with optional suffix (optional suffix)  
3: (optional suffix)  

编辑:在正则表达式上面更新,以允许在结束括号后的空白(这很微妙,您需要将空间添加到负字符类),并锚定正则表达式以加速和减少回溯

 类似资料:
  • 问题内容: 我如何制作像这样的python正则表达式,使得在给定的情况下,python匹配而不是? 我知道我可以使用代替,但是我正在寻找一种更通用的解决方案,使我的regex更加整洁。有什么办法告诉python“嘿,尽快匹配它”? 问题答案: 您寻找功能强大的吗? http://docs.python.org/3/howto/regex.html#greedy-versus-non-greedy

  • 问题内容: 我主要关心的是Java风格,但是我也希望了解其他信息。 假设您有一个像这样的子模式: 虽然这不是很有用,但可以说这两个捕获组(例如和)是更大模式的一部分,该模式与对这些组的反向引用匹配,依此类推。 因此,两者都是贪婪的,因为他们试图捕获尽可能多的东西,只在需要时花更少的时间。 我的问题是:谁更贪婪?是否获得优先权,仅在必要时才分配份额? 关于什么: 假设确实获得了优先权。假设它过于贪婪

  • 问题内容: 我有下一个代码: 并具有下一个输出: 但我认为它必须是: 有人请解释为什么。 问题答案: 由于您的模式是非贪婪的,因此它们在仍由匹配项组成的情况下,匹配的文本越少越好。 去除 ?在第二组中,您会得到 单词 word word big small

  • 本文向大家介绍python正则表达式的懒惰匹配和贪婪匹配说明,包括了python正则表达式的懒惰匹配和贪婪匹配说明的使用技巧和注意事项,需要的朋友参考一下 第一次碰到这个问题的时候,确实不知道该怎么办,后来请教了一个大神,加上自己的理解,才了解是什么意思,这个东西写python的会经常用到,而且会特别频繁,在此写一篇博客,希望可以帮到一些朋友。 例:一个字符串 “abcdacsdnd” ①懒惰匹配

  • 本文向大家介绍php正则表达式中贪婪与非贪婪介绍,包括了php正则表达式中贪婪与非贪婪介绍的使用技巧和注意事项,需要的朋友参考一下 一、贪婪与非贪婪 什么叫贪婪,比如说要从字符串中<td>面包一</td><td>面包二</td>吃面包,本来你只可以吃面包一,可是你贪心,于是就把第一个<td>到最后一个</td>里面的两个面包取出来了,你想多吃点,非贪婪也就是你不贪吃了,就只吃面包一。 我们来看看正

  • 问题内容: 这种模式仅意味着将字符串中的所有内容抓取到数据中第一个潜在句子边界为止: 输出: 从Python文档中: re.findall(模式,字符串,标志= 0) 返回字符串中模式的所有非重叠匹配项,作为字符串列表。从左到右扫描字符串,并以找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回一个组列表;否则,返回一个列表。如果模式包含多个组,则这将是一个元组列表。空匹配项将包括在结果中,除