如何解析时间范围输入?

发布于 2024-09-29 04:45:14 字数 455 浏览 0 评论 0原文

在我正在开发的程序中,我需要用户输入时间范围,例如2002-2003,或1999-(隐含现在),或-2000(2000年之前)。

我有一个对象的 ArrayList,因此用户可能会将其作为书名,包括一些信息(其中之一必须是出版日期)。然后他们可以搜索特定的书籍,时间范围是实现这一目标的方法之一。

因此,我将他们想要的日期范围作为字符串,并将日期作为整数存储在我的对象中。我了解这些案例,并且我尝试涵盖所有案例,但在“-2010”和“2010-”以及“2010”案例方面遇到了问题。

据我所知,这些案例有: -2010年 2010年 2010-2011 2011-

任何人都可以提出一个基本算法,或者概述一些有用的函数吗?

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

感谢大家的帮助。

In a program I'm working on, i need the user to input time ranges, such as 2002-2003, or 1999- (implied present), or -2000 (before 2000).

I have an ArrayList of objects, and so the user might put it the title of books, including some information (one of these must be the date it was published). They can then search for a specific book, and time range is one of the ways to do it.

So i've taken in the date range they want as a String, and I have the date stored in my object as a integer. I know the cases, and I've tried to cover all the cases, but am having problems with the '-2010' and '2010-', and the '2010' cases.

The cases, as far as I can tell are:
-2010
2010
2010-2011
2011-

could anyone suggest a basic algorithm, or perhaps outline some useful functions?

My idea was that by the end of the parsing, i should have a minimum and maximum date, such that i can look at a particular book, and ask, is the date it provided bigger than the minimum, and smaller than the maximum? But i still need to parse the ranges.

Thanks for the help everyone.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浮光之海 2024-10-06 04:45:14

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

^(\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() 表示您找到的内容,? 表示此组对于匹配是可选的,组将 == null
(-)? - 查找破折号,? 使其可选,() 对上面的结果进行分组
(\d{4})? - 这会查找 4 位数字 \d() 表示您找到的内容,? 表示此组对于匹配是可选的,组将 == null
$ - 匹配行尾

留给读者的练习: 它不“验证”的两种情况是空字符串和“-” ,这两种情况都应该被视为“特殊”情况,具体取决于您希望业务逻辑是什么。

As much as I usually abhor regular expressions this is a great place for using them. You get data validation as well as parsing all in one shot with the correct use of grouping.

^(\d{4})?(-)?(\d{4})?$ will give you 3 output groups, you check each one to see if you got a value and make decisions based on that, and as a bonus you are guaranteed that they are 4 digit numbers. Look at the groups on the Rubular page I link to. If you have a value in group 1 then that is the start year, a "-" in group two then it is a range, a value in group 3 an end range. Makes the logic really simple and you don't have to do all that silly string manipulation and Integer testing that other solutions suggest.

Since this is homework, here is something to kick start your thinking, how to use the Pattern and Matcher, I am not going to do the entire thing for you.

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));
            }
        }
    }
}

Here is the expected output:

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

How it works:

^ - start at the beginning of the line
(\d{4})? - this looks for exactly 4 digits \d and the () says group what you find, ? means this group is optional for a match, group will == null
(-)? - this looks for the dash, ? makes it optional, () groups the results at above
(\d{4})? - this looks for exactly 4 digits \d and the () says group what you find, ? means this group is optional for a match, group will == null
$ - matches the end of the line

Exercise left for the reader: The two cases it doesn't "validate" for is an empty string and "-", both of which should be considered "special" cases depending on what you want your business logic to be.

旧夏天 2024-10-06 04:45:14

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

Check if the first character is a -.
Then check if the last character is a -.
If it is neither of those cases, split at the - (use the String class's split method).

江湖彼岸 2024-10-06 04:45:14

您可以使用 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));
}

You can parse with the String.indexOf() function

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));
}
半暖夏伤 2024-10-06 04:45:14
  1. 使用 StringTokenizer 解析日期(或简单地使用 String#indexOf 方法)
  2. 使用 DateFormat 构建相关日期
  3. 使用 Date 对象的 before/after 方法进行相关比较以找出日期范围。
    http://download.oracle.com/javase/6/docs/api/
  1. Use StringTokenizer to parse date(or simply use String#indexOf method)
  2. Use DateFormat to build relevant dates
  3. Use Date object's methods before/after for relevant comparisons to figure out the date range.
    http://download.oracle.com/javase/6/docs/api/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文