Java 缩短正则表达式

Java 缩短正则表达式,java,regex,Java,Regex,在Java正则表达式中,我有以下内容: (1abc\\d{2})|(2abc\\d{3})|(3abc\\d{4}) 我想从正则表达式中提取“abc\d”,并用如下内容替换正则表达式: (1|2|3)abc\\d({2]|{3}|{4}) 问题是1属于{2},2属于{3},3属于{4}。所以,好的匹配是1abc12,坏的匹配是1abc123 我最近学习了RegEx,我觉得我缺少了一些关于RegEx的知识来实现这一点。甚至可能吗?由于数字1、2、3分别与正则表达式组{2}、{3}和{4}有点关

在Java正则表达式中,我有以下内容:

(1abc\\d{2})|(2abc\\d{3})|(3abc\\d{4})
我想从正则表达式中提取“abc\d”,并用如下内容替换正则表达式:

(1|2|3)abc\\d({2]|{3}|{4})
问题是1属于{2},2属于{3},3属于{4}。所以,好的匹配是1abc12,坏的匹配是1abc123


我最近学习了RegEx,我觉得我缺少了一些关于RegEx的知识来实现这一点。甚至可能吗?

由于数字1、2、3分别与正则表达式组{2}、{3}和{4}有点关联,我认为没有办法扩展公共子表达式。

正则表达式无法实现您所描述的。通常,表达式的后面部分不能依赖于表达式前面部分的匹配结果。例如,您不能编写匹配平衡括号或括号的正则表达式


有些实现提供了例外情况的扩展(不规则表达式),但我认为它们不适用于这里。

您可以通过正则表达式中的
\n
使用反向引用来引用以前匹配的组,但这些仅再次匹配字符串,无法更改模式的规则

例如,
(1 | 2 | 3)abc\1
将匹配
1abc1
2abc2
,但不匹配
1abc2
,即
\1
将匹配在第一个括号中找到的内容

理想情况下,我们希望做一些事情,但是Java不支持正则表达式中的代码或表达式


因此,不幸的是,您想要的是不可能的,或者说您的第一个表达式可能已经达到了预期的效果。

这不是一个完美的解决方案,但是您可以使用字符串函数提取第一个数字(或者如果格式不能保证是适当的模式,则使用正则表达式)。然后用第一个数字加上一个,并在一个非常简单的正则表达式中使用它。

这可以用一种伪条件的方式来完成,但治疗可能比疾病更糟糕

我使用这样的东西(下面)的唯一方法是,如果“文本”(在本例中是abc)非常大,以这种方式分解它将产生时间收益,而不是像现在这样将它包含在每个替换中。一些非常大的文本示例可能是“
abc[^\d]+432xyz
”,或者任何具有开放式量词或导致巨大回溯的文本

这在Java中起作用

“^(?:1()| 2()| 3())abc(?:(?=\\1)\\d{2}|(?=\\2)\\d{3}|(?=\\3)\\d{4})$”

(扩大)

另外,正如有人提到的,您可以进行一般捕获,然后对结果进行后期处理以确定其是否有效


类似这样:
^(1 | 2 | 3)abc(\d{2,4})$
。然后在捕获缓冲区1上进行切换,然后在捕获缓冲区2的长度上进行案例分析。

作为一种可能的替代方法,放松与第二个表达式类似的匹配条件(但更简单),并在捕获组1和2上使用java逻辑来筛选结果的好坏
\1\d{2}
同样有效。Dave Webb他的答案也很好,但加入“不规则表达”一词,让我更清楚地解释了为什么我试图做的是不可能的。
^       # Begin, all capture buffers are undefined and empty
  (?:
      1()     # If '1' found, set capture buffer 1 to defined (but empty)
    | 2()     # If '2' found, set capture buffer 2 to defined (but empty)
    | 3()     # If '3' found, set capture buffer 3 to defined (but empty)
  )
  abc      # The text factored out
  (?:
       # The below could also be  \1\d{2}|\2\d{3}|\3\d{4} as well

      (?=\1)\d{2}    #     Assertion: is capt buffer 1 defined?, get next two digits
    | (?=\2)\d{3}    # or, Assertion: is capt buffer 2 defined?, get next three digits
    | (?=\3)\d{4}    # or, Assertion: is capt buffer 3 defined?, get next four digits
  )
$      # End