如何解析时间范围输入?

时间:2010-10-25 20:38:11

标签: java string character

在我正在研究的程序中,我需要用户输入时间范围,例如2002-2003或1999-(暗示存在)或-2000(2000年之前)。

我有一个对象的ArrayList,因此用户可能会把它放在书的标题上,包括一些信息(其中一个必须是它发布的日期)。然后,他们可以搜索特定的书籍,时间范围是其中一种方法。

所以我把他们想要的日期范围作为一个字符串,我将日期存储在我的对象中作为整数。我知道这些案件,并且我试图涵盖所有案件,但我对'-2010'和'2010-'以及'2010'案件都有疑问。

据我所知,案件包括: -2010 2010 2010-2011 2011-

有人可以建议一个基本的算法,或者可能概述一些有用的功能吗?

我的想法是,在解析结束时,我应该有一个最小和最大日期,这样我可以看一本特定的书,并问,它提供的日期是否大于最小值,并且小于最大值?但是我仍然需要解析范围。

感谢大家的帮助。

4 个答案:

答案 0 :(得分:3)

尽管我通常厌恶正则表达式,但这是一个使用它们的好地方。您可以通过正确使用分组来获得数据验证以及一次性解析。

^(\d{4})?(-)?(\d{4})?$将为您提供3个输出组,您可以检查每个输出组以查看是否有值并根据该值做出决定,并且作为奖励,您可以保证它们是4位数字。查看我链接到的Rubular页面上的组。如果您在组1中有值,那么这是开始年份,第2组中的“ - ”则是范围,第3组中的值是结束范围。使逻辑非常简单,您不必执行其他解决方案所建议的所有愚蠢的字符串操作和整数测试。

由于这是家庭作业,这里有一些启动你的想法,如何使用PatternMatcher,我不会为你完成整个事情。

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main
{
    public static void main(String[] args)
    {
        final List<String> inputs = Arrays.asList("1999-", "-2010", "1990-2000", "1967");

        final Pattern p = Pattern.compile("^(\\d{4})?(-?)(\\d{4})?$");
        int count = 0;
        for (final String input : inputs)
        {
            final Matcher m1 = p.matcher(input);
            m1.find();
            System.out.format("Input: %d\n", count++);
            for (int i=1; i <= m1.groupCount(); i++)
            {
                System.out.format("\tGroup %d = %s\n", i, m1.group(i));
            }
        }
    }
}

以下是预期输出:

Input: 0
 Group 1 = 1999
 Group 2 = -
 Group 3 = null
Input: 1
 Group 1 = null
 Group 2 = -
 Group 3 = 2010
Input: 2
 Group 1 = 1990
 Group 2 = -
 Group 3 = 2000
Input: 3
 Group 1 = 1967
 Group 2 = 
 Group 3 = null

工作原理:

^ - 从行的开头开始
 (\d{4})? - 这会查找4位\d,而()表示您找到的内容,?表示此群组对于匹配是可选的,群组将{{1} }
 == null - 这会查找短划线,(-)?将其设为可选,?将结果分组在上面
 () - 这会查找4位(\d{4})?,而\d表示您找到的内容,()表示此群组对于匹配是可选的,群组将{{1} }
 ? - 匹配行尾

为读者留下的练习: 它没有“验证”的两种情况是一个空字符串和“ - ”,两者都应视为“特殊”情况依赖关于你希望你的业务逻辑是什么。

答案 1 :(得分:1)

检查第一个字符是否为 - 。 然后检查最后一个字符是否为 - 。 如果它不是这些情况,则拆分 - (使用String类的split方法)。

答案 2 :(得分:0)

您可以使用String.indexOf()函数解析

int startDate, endDate, middleIndex;
middleIndex = inputString.indexOf("-");
if (middleIndex == -1)       //If there's no hyphen
  startDate = endDate = Integer.parseInt(inputString);
else if (middleIndex == 0) {  //if the hyphen is at the start of the string
  startDate = null;
  endDate = Integer.parseInt(inputString.substring(1, inputString.length));
}
else if (middleIndex == inputString.length - 1) {  //if the hyphen is at the end of the string
  startDate = Integer.parseInt(inputString.substring(0, inputString.length - 1));
  endDate = null;
}
else {  //if the hyphen separates 2 years
  startDate = Integer.parseInt(inputString.substring(0, middleIndex));
  endDate = Integer.parseInt(inputString.substring(middleIndex + 1, inputString.length));
}

答案 3 :(得分:0)

  1. 使用StringTokenizer来解析日期(或简单地使用String #indexOf方法)
  2. 使用DateFormat构建相关日期
  3. 在相关比较之前/之后使用Date对象的方法来计算日期范围。 http://download.oracle.com/javase/6/docs/api/