解析番石榴范围的区间符号

时间:2015-11-05 18:59:05

标签: java parsing guava

我需要将包含标准区间符号(即(8,100),[6,10)等)的字符串解析为Guava Range对象。我将如何在Java中实现这一目标?是否有一个实用程序包可以将字符串解析为构建Guava Range对象所需的组件?

1 个答案:

答案 0 :(得分:4)

如果我们查看模式,则时间间隔以'[''('开头,然后是至少一个数字,后跟逗号,再一个或多个数字,由']'')'完成。

因此正则表达式将如下所示:

^[\\(|\\[](\\d+),(\\d+)[\\)|\\]]$

这里被分解了:

^
 [\\(|\\[] -> start either with `'['` or `'('` (we need to escape the special characters with `\\`)
 (\\d+) -> followed by one or more digit that we capture in a group
 , -> followed by a comma
 (\\d+) -> followed again by one or more digit that we capture in another group
 [\\)|\\]] -> and that finishes either with `']'` or `')'`
$

^$断言所有字符串与表达式匹配,而不仅仅是表达式的一部分。

所以我们有正则表达式,耶!

现在我们需要从中创建一个Pattern实例,以便能够从中获取匹配器。最后,我们检查字符串是否与模式匹配,然后我们获取相应的组

Pattern p = Pattern.compile("^[\\(|\\[](\\d+),(\\d+)[\\)|\\]]$");
Matcher m = p.matcher("(0,100)");

if(matcher.matches()) {
    int lowerBound = Integer.parseInt(matcher.group(1));
    int upperBound = Integer.parseInt(matcher.group(2));
    System.out.println(lowerBound + "_" + upperBound);
}

以下输出0_100

现在是最后一步,获取第一个和最后一个字符并从中创建适当的范围;把它们放在一起:

class RangeFactory {

    private static final Pattern p = Pattern.compile("^[\\(|\\[](\\d+),(\\d+)[\\)|\\]]$");

    public static Range from(String range) {
        Matcher m = p.matcher(range);
        if(m.matches()) {
            int length = range.length();

            int lowerBound = Integer.parseInt(m.group(1));
            int upperBound = Integer.parseInt(m.group(2));

            if(range.charAt(0) == '(') {
                if(range.charAt(length - 1) == ')') {
                    return Range.open(lowerBound, upperBound);
                }
                return Range.openClosed(lowerBound, upperBound);
            } else {
                if(range.charAt(length - 1) == ')') {
                    return Range.closedOpen(lowerBound, upperBound);
                }
                return Range.closed(lowerBound, upperBound);
            }
        }
        throw new IllegalArgumentException("Range " + range + " is not valid.");
    }
}

以下是一些测试用例:

List<String> ranges =
    Arrays.asList("(0,100)", "[0,100]", "[0,100)", "(0,100]", "", "()", "(0,100", "[,100]", "[100]");

for(String range : ranges) {
    try {
        System.out.println(RangeFactory.from(range));
    } catch (IllegalArgumentException ex) {
        System.out.println(ex);
    }
}

输出:

(0‥100)
[0‥100]
[0‥100)
(0‥100]
java.lang.IllegalArgumentException: Range  is not valid.
java.lang.IllegalArgumentException: Range () is not valid.
java.lang.IllegalArgumentException: Range (0,100 is not valid.
java.lang.IllegalArgumentException: Range [,100] is not valid.
java.lang.IllegalArgumentException: Range [100] is not valid.

你可以改善正则表达式(接受具有无限边界的范围等),但它应该给你一个很好的起点。

希望它有所帮助! :)