Java 试图简化复杂的正则表达式

Java 试图简化复杂的正则表达式,java,regex,perl,Java,Regex,Perl,例如,以下正则表达式试图解释所有可能的、有效的非军事时间间隔。如:“04-12:15”、“12:30-9”、“3:10-4:57”,但不符合以下内容: “2013-11-04” Regex(从另一个类似问题贷记到@MikeClark for Regex): 所以我的问题是: (1): 有没有办法引用正则表达式的一部分?反向引用不起作用,因为我想要的不是表达式匹配的内容(假设它是一个捕获组),而是表达式本身。我知道可以将表达式存储在字符串中并使用format(),但我想看看是否可以仅在正则表达式中

例如,以下正则表达式试图解释所有可能的、有效的非军事时间间隔。如:“04-12:15”、“12:30-9”、“3:10-4:57”,但不符合以下内容:

“2013-11-04”

Regex(从另一个类似问题贷记到@MikeClark for Regex):

所以我的问题是:

(1): 有没有办法引用正则表达式的一部分?反向引用不起作用,因为我想要的不是表达式匹配的内容(假设它是一个捕获组),而是表达式本身。我知道可以将表达式存储在字符串中并使用
format()
,但我想看看是否可以仅在正则表达式中执行此操作

(2): 我唯一能想到的另一件事是能够确定表达式中的哪个重复。例如:

给定:
regex=“…(?:someExpression){2}”

有没有办法确定我们是在第一次还是第二次重复
someExpression

关于
Java
Perl
的答案最适合我


谢谢你的帮助

可能是最短/最简单的版本:

包片段

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.regex.Pattern;

import org.junit.Test;

public class RegexTest {

    @Test
    public void test() {
        Pattern p = Pattern.compile("(0?[0-9]|1[0-2])(:[0-5][0-9])?-(0?[0-9]|1[0-2])(:[0-5][0-9])?");
        assertFalse(p.matcher("0").matches());
        assertFalse(p.matcher("1:00").matches());
        assertFalse(p.matcher("9:59").matches());
        assertFalse(p.matcher("10:01").matches());
        assertFalse(p.matcher("12").matches());

        assertTrue(p.matcher("04-12:15").matches());
        assertTrue(p.matcher("12:30-9").matches());
        assertTrue(p.matcher("3:10-4:57").matches());

        assertFalse(p.matcher("9:6").matches());
        assertFalse(p.matcher("9:60").matches());
        assertFalse(p.matcher("13").matches());
        assertFalse(p.matcher("20").matches());
        assertFalse(p.matcher("20:").matches());
        assertFalse(p.matcher("20-").matches());
        assertFalse(p.matcher(":20").matches());
        assertFalse(p.matcher("-20").matches());
    }

}
关于你的问题:

(1) 据我所知,不是你需要的那种方式。反向引用期望的值与第一次相同


(2) 据我所知并非如此。

可能是最短/最简单的版本:

包片段

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.regex.Pattern;

import org.junit.Test;

public class RegexTest {

    @Test
    public void test() {
        Pattern p = Pattern.compile("(0?[0-9]|1[0-2])(:[0-5][0-9])?-(0?[0-9]|1[0-2])(:[0-5][0-9])?");
        assertFalse(p.matcher("0").matches());
        assertFalse(p.matcher("1:00").matches());
        assertFalse(p.matcher("9:59").matches());
        assertFalse(p.matcher("10:01").matches());
        assertFalse(p.matcher("12").matches());

        assertTrue(p.matcher("04-12:15").matches());
        assertTrue(p.matcher("12:30-9").matches());
        assertTrue(p.matcher("3:10-4:57").matches());

        assertFalse(p.matcher("9:6").matches());
        assertFalse(p.matcher("9:60").matches());
        assertFalse(p.matcher("13").matches());
        assertFalse(p.matcher("20").matches());
        assertFalse(p.matcher("20:").matches());
        assertFalse(p.matcher("20-").matches());
        assertFalse(p.matcher(":20").matches());
        assertFalse(p.matcher("-20").matches());
    }

}
关于你的问题:

(1) 据我所知,不是你需要的那种方式。反向引用期望的值与第一次相同


(2) 据我所知不是这样。

有没有办法引用正则表达式的一部分?

是的。您可以使用符号
(?1)
来重用第一个定义组。就你而言,它是:

(?<!\d|-|:)(((?:0?[1-9]|1[0-2])(?::[0-5][0-9])?)-(?2))(?!\d|-|:)
(?

您必须再创建一个组。

是否有方法引用正则表达式的一部分?

是的。您可以使用符号
(?1)
来重用第一个定义组。在您的情况下,它是:

(?<!\d|-|:)(((?:0?[1-9]|1[0-2])(?::[0-5][0-9])?)-(?2))(?!\d|-|:)
(?

你必须再做一组。

你误解了这个问题。单个时间不应该匹配。这里的重点是匹配时间间隔。只有时间间隔?它也匹配时间间隔。是的,只有时间间隔。这是不正确的。按照这个逻辑,你最终会得到我拥有的正则表达式。我问这个问题的原因是这个问题是为了能够简化正则表达式。如果可能的话,我问的两个问题将有助于做到这一点。例如,您的问题在您自己的输入时失败:“3:10-4:57”。此外,请考虑类似这样的问题:
“2013-11-04”
,这应该根本不匹配。1.单元测试失败,如果您运行它?!?2.“2013-11-04”与我使用的模式不匹配。3.你阅读了我对你的问题的回答?你误解了问题。单一时间不应该匹配。这里的重点是匹配时间间隔。只有时间间隔?它也匹配时间间隔。是的,只有时间间隔。这是不正确的。按照这种逻辑,你最终会得到是的。我问这个问题的原因是为了能够简化正则表达式。如果可能的话,我问的两个问题将有助于做到这一点。例如,你的问题在你自己的输入上失败:“3:10-4:57”。此外,想想类似这样的问题:
“2013-11-04”
,这根本不应该匹配。1.如果您运行unittest,它会失败?!2.“2013-11-04”与我使用的模式不匹配。3.您阅读了我对您的问题的回答吗?谢谢,我忘记了perl中的递归模式(仅供参考,它只是
\d
)。当然,我现在意识到给定的正则表达式实际上是不正确的(好的,一切都是固定的(我更新了你的答案和我的问题),但正如我预期的那样,一切都成功了!谢谢!谢谢!我忘记了perl中的递归模式(仅供参考)
\d
)。当然,我现在意识到给出的正则表达式实际上是不正确的。:(好的,一切都是固定的(我更新了你的答案和我的问题),但正如我所料,它成功了!谢谢!