【问题标题】:How to identify date from a string in Java如何从Java中的字符串中识别日期
【发布时间】:2016-02-06 10:37:01
【问题描述】:

最近我遇到了一个相当“简单”的问题。假设有句子(保存在一个String中),我需要找出这个String中是否有任何日期。挑战在于日期可以采用许多不同的格式。列表中显示了一些示例:

  • 1956 年 6 月 12 日
  • 伦敦,2014 年 10 月 21 日
  • 1999 年 10 月 13 日
  • 01/11/2003

值得一提的是,这些都包含在一个字符串中。举个例子,它可以是:

String s = "This event took place on 13 October 1999.";

在这种情况下,我的问题是如何检测到此字符串中有日期。我的第一种方法是搜索“事件”一词,然后尝试本地化日期。但是随着日期的可能格式越来越多,这个解决方案不是很漂亮。我尝试的第二个解决方案是创建几个月的列表并进行搜索。这有很好的结果,但仍然错过了日期全部用数字表示的情况。

到目前为止我还没有尝试过的一种解决方案是设计正则表达式并尝试在字符串中找到匹配项。不确定此解决方案可能会降低多少性能。

我可能应该考虑什么是一个好的解决方案?以前有没有人遇到过类似的问题,您找到了哪些解决方案?

一件事是肯定没有时间,所以唯一有趣的部分是日期。

【问题讨论】:

  • 我能想到接近这个问题的唯一方法是结合你所有的方法。例如。在字符串中查找月份,然后尝试查找美国日期(MM/DD/YYYY),然后尝试查找欧洲日期(DD.MM.YYYY).....这取决于什么样的字符串你收到!如果某个字符串包含“它发生在 1989 年第二个月的第一天”,您可能无法实现它!)
  • 唯一的办法就是解析你的字符串。
  • 我记得有一个人有同样的问题:stackoverflow.com/questions/33098511/…
  • 这不是一个简单的问题。如果您需要确定日期是什么,这是无法解决的:您的最后一个示例可能是 11 月 1 日或 1 月 11 日

标签: java string date parsing


【解决方案1】:

使用natty.joestelmach.com

Natty 是用 Java 编写的自然语言日期解析器。给定一个日期表达式,natty 将应用标准语言识别和翻译技术来生成一个包含可选解析和语法信息的对应日期列表。

import com.joestelmach.natty.*;

List<Date> dates =new Parser().parse("Start date 11/30/2013 , end date Friday, Sept. 7, 2013").get(0).getDates();
        System.out.println(dates.get(0));
        System.out.println(dates.get(1));

//output:
//Sat Nov 30 11:14:30 BDT 2013
//Sat Sep 07 11:14:30 BDT 2013

【讨论】:

  • 在我尝试过的所有东西中,这个效果最好。
  • 我认为GATEANNIE 做得更好。
【解决方案2】:

你在Named Entity Recognition之后。我将从Stanford NLP 开始。 7类机型包括日期,但网上demo struggles又漏掉了“13”。 :(

上面提到的 Natty 给出了一个better answer

【讨论】:

    【解决方案3】:

    如果它只有一个字符串,您可以使用您提到的正则表达式。必须找到不同的日期格式表达式。这里有些例子: Regular Expressions - dates

    如果是文档或大文本,您将需要一个解析器。您可以使用Lexical analysis 方法。

    根据某些答案中提到的使用外部库的项目可能是一个好主意。有时这不是一个选择。

    【讨论】:

    • 正则表达式对此会很困难
    【解决方案4】:

    我以前用好的precisionrecall 做过这个。你需要GATE 和它的ANNIE 插件。

    1. 使用 GATE UI 工具创建一个 .GAPP 文件,该文件将包含您的 processing resources

    2. 使用.GAPP 文件来使用提取的Date 注释集。

    步骤2可以如下进行:

    Corpus corpus = Factory.newCorpus("Gate Corpus");
    Document gateDoc = Factory.newDocument("This event took place on 13 October 1999.");
    corpus.add(gateDoc);
    File pluginsHome = Gate.getPluginsHome();
    File ANNIEPlugin = new File(pluginsHome, "ANNIE");
    File AnnieGapp = new File(ANNIEPlugin, "Test.gapp");
    AnnieController =(CorpusController) PersistenceManager.loadObjectFromFile(AnnieGapp);
    AnnieController.setCorpus(corpus);
    AnnieController.execute();
    

    稍后你可以看到像这样提取的注释:

    AnnotationSetImpl ann = (AnnotationSetImpl) gateDoc.getAnnotations();
    System.out.println("Found annotations of the following types: "+ gateDoc.getAnnotations().getAllTypes());
    

    我相信您可以使用内置注释集 Date 轻松完成此操作。它也非常可增强。

    为了增强注释集DateJAPE 中创建一个宽松的注释规则,从内置的ANNIE 注释Date 中说“DateEnhanced”以包含某些类型的日期,例如“9/11”并使用Java 正则表达式的链接在 RHS 上'DateEnhanced' 注释 JAPE RULE,以过滤一些不需要的输出(如果有)。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 2020-08-20
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 1970-01-01
    相关资源
    最近更新 更多