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

时间:2013-11-05 01:54:43

标签: java regex perl

例如,以下正则表达式尝试考虑所有可能的,有效的非军事时间间隔。如:“04-12:15”,“12:30-9”,“3:10-4:57”,但不会与之相提并论:

"<td class="text">2013-11-04</td>"

Regex(从另一个类似的问题归功于@MikeClark for regex):

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

以下是正则表达式的解释:

(?<!\\d|-|:)数字,连字符或冒号的负面后视 (?:0?[1-9]|1[0-2])所有有效时间的帐户
(?::[0-5][0-9])所有有效会议记录的帐户
(?!\\d|-|:)数字,连字符或冒号的否定预测

希望其余的都是自我解释的。这有效,但它非常冗长。从理论上讲,这可以简化为:
设EXP = (?:0?[1-9]|1[0-2])(?:[0-5][0-9])?

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

所以我的问题是:

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

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

鉴于:regex = "...(?:someExpression){2}"

有没有办法确定我们是否在someExpression的1 st 或2 nd 重复?

JavaPerl相关的答案最适合我。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

Is there any way to reference part of a regular expression?

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

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

你必须再组一个小组。

答案 1 :(得分:0)

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

包裹摘要;

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)据我所知,你不需要这样做。反向引用的值与第一次相同。 http://www.regular-expressions.info/backref.html

(2)据我所知。