【问题标题】:Fastest/Easiest Way to Parse Text解析文本的最快/最简单方法
【发布时间】:2015-04-09 22:00:23
【问题描述】:

我正在尝试解析一些文本,正在寻找最快/最简单的解决方案。我尝试过使用正则表达式,但使用 Java 需要很长时间......

这是我要解析的文本的结构:

*****************
ID: 1234567  // 7 digit uuid
mistakes: There may be some mistakes here, or there may not be any mistakes  //optional
mistake type: mistake background // "YES" or "NO"
report: <xml><item>blah, blah</item></xml> 

*****************

实际上该文件可能如下所示:

*****************
ID: 1234567
mistakes: 
NO: happened on the playground
report: <xml><item>black eye when playing basketball</item><reason>elbow</reason></xml> 

*****************

*****************
ID: 1234568
mistakes: Teacher was not watching students at the time of incident
YES: teacher turned her back after seeing an altercation
report: <xml><item>fight</item><reason>None</reason></xml> 

*****************

*****************
ID: 1234569
mistakes:
NO
report: <xml><item>Child needed band-aid</item><reason>scrape</reason></xml> 

*****************

*****************
ID: 1234570
mistakes:
NO
report: <xml><item>Child needed tissue</item><reason>runny nose</reason></xml> 

*****************
...
...

我正在尝试将“键”(ID、错误、错误类型、报告)放入Map 以进行进一步聚合和处理。

我尝试过使用正则表达式,但收效甚微,但客户不断更改报告结构并放弃整个模式。我正在寻找可能更容易维护的东西。过去,我很容易对这样的数据进行 xsl 转换,但这不是纯 xml,我不知道 Java 是否会抛出当前格式。我已询问客户是否愿意更改格式,但他们对此不感兴趣。

有人对如何使这种解析更易于维护有任何想法吗?

谢谢!


编辑:

我没有正则表达式,但这是它的要点

ID:\s*(\\d{7}).*mistakes:\s*(\\d*).*mistake type:\s*(\\d*).*report:\s*(.*)

【问题讨论】:

  • 嗯,正则表达式必须非常简单地描述这种格式,只要格式发生变化就更新它们可能没什么大不了的。
  • 每次更新都会让人头疼。它似乎总是会破坏某些东西,我需要用几天的谷歌搜索等来找出原因
  • 格式一开始就不应该这么频繁地改变...我们可以看看一些代码吗?
  • 不同意单个正则表达式。该文件遵循您应该遵循的严格结构。至少对于最后一个(报告),您应该单独解析为 xml。只需流过期待这种结构的线条,并在你走的时候打破填充你的对象列表的星星。
  • @Vedran 我已经在解析报告了。我正试图专注于“挑选钥匙”(ID、MISTAKE、MISTAKE TYPE、REPORT)

标签: java text-parsing


【解决方案1】:

我还不能对帖子发表评论,这就是为什么我会留下这个作为答案。如果您有固定数量的字段,您可以逐行读取,并且在您的行startsWith("^\.*") 之后只写6 行。然后,您将继续使用类似的逻辑将它们存储在地图中。如果它 startsWith("^mistakes:") 则存储剥离 ":mistakes" 后剩下的任何值。

【讨论】:

    【解决方案2】:

    您可以尝试使用常规的字符串操作。例如对于包含

    的行

    ID:1234567

    类似

    if (line.startsWith("ID:")
    {
        String id = line.subString(3).trim();
    }
    

    显然事先检查该行是否为空白/空。我相当肯定它会更快。

    另请参阅此博文Performance Comparison: Regex versus string operations

    【讨论】:

    • 我有超过 200 个这样的“组”要解析。我不想逐行解析它们。
    • 对不起,没有看到代码,我以为正在使用 BufferedReader。如果您将整个文件读入内存,我仍然看不到正则表达式的原因,因为项目标识符是静态的。如果标识符是 ID1:、ID2 等,我通常使用正则表达式
    • 如果你不推荐使用正则表达式,你会推荐什么?
    • @Dan:我已经使用这种类型的操作解析了数千行的文件。我认为解析时间不会超过 2 秒。你确定你用不起这种方法吗?
    • @Dan 我的回答中的常规字符串比较。
    【解决方案3】:

    我想我会继续使用带有 readline 扭曲的正则表达式。

    我会将我的正则表达式更改为"\\*{17}.*\\*{17}",一旦我将它们按“*”分组,我就可以逐行读取它们,并按它们的 ID 将它们放入我的地图中。

    【讨论】:

      【解决方案4】:

      如果您使用的是 java,为什么不尝试将此文件加载为属性文件。然后您可以使用 propFile.getProperty("key") 阅读此内容。这样您可能不需要地图,或者即使您需要地图,您也可以使用 propFile.propertyNames() 使用枚举并将其放置在地图中。

      【讨论】:

      • 这个想法的问题是同一个键值在一个基于示例的文件中多次出现。
      猜你喜欢
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2020-08-27
      • 1970-01-01
      • 2011-03-03
      • 2010-09-06
      相关资源
      最近更新 更多