代码之家  ›  专栏  ›  技术社区  ›  M. A. Kishawy Andy Guibert

如何从没有常量清除器的文本行中提取字段?

  •  1
  • M. A. Kishawy Andy Guibert  · 技术社区  · 14 年前

    如果每个字段之间没有明确的分隔符(除颤器),那么从每行中提取每个字段的最佳方法是什么?

    以下是我需要提取其字段的行示例:

    3/3/2010 11:00:46 AM                      BASEMENT-IN          
    3/3/2010 11:04:04 AM 2, YaserAlNaqeb      BASEMENT-OUT         
    3/3/2010 11:04:06 AM                      BASEMENT-IN          
    3/3/2010 11:04:18 AM                      BASEMENT-IN          
    3/3/2010 11:14:32 AM 4, Dhileep              BASEMENT-OUT         
    3/3/2010 11:14:34 AM                      BASEMENT-IN          
    3/3/2010 11:14:41 AM                      BASEMENT-IN          
    3/3/2010 11:15:33 AM 4, Dhileep           BASEMENT-IN          
    3/3/2010 11:15:42 AM                      BASEMENT-IN          
    3/3/2010 11:15:42 AM                      BASEMENT-IN          
    3/3/2010 11:30:22 AM 34, KumarRaju        BASEMENT-IN          
    3/3/2010 11:31:28 AM 39, Eldrin           BASEMENT-OUT         
    3/3/2010 11:31:31 AM                      BASEMENT-IN          
    3/3/2010 11:31:39 AM                      BASEMENT-IN          
    3/3/2010 11:32:38 AM 39, Eldrin           BASEMENT-IN          
    3/3/2010 11:32:47 AM                      BASEMENT-IN          
    3/3/2010 11:32:47 AM                      BASEMENT-IN          
    3/3/2010 11:33:26 AM 34, KumarRaju        BASEMENT-OUT         
    3/3/2010 11:33:28 AM                      BASEMENT-IN    
    

    每行有6个字段,其中一些可以为空。解决这个问题的最好方法是什么?

    • 我使用Java

    第01版

    • 字段5可以为空(但是在所有情况下都应该承认它的存在)
    • 可以更改的空间量
    • 最后一句话可以改变
    6 回复  |  直到 14 年前
        1
  •  1
  •   extraneon    14 年前

    对我来说,似乎有3个元字段:

    3/3/2010 11:32:38 AM 39, Eldrin           BASEMENT-IN          
    3/3/2010 11:32:47 AM                      BASEMENT-IN 
    

    MF1: 3/3/2010 11:32:38 AM

    MF2: 39, Eldrin

    MF3: BASEMENT-IN

    其中mf2是可选的。我的分隔符是:

    MF1至[上午下午]

    MF2号,地下室除外-*

    MF3地下室-*

    我不太擅长正则表达式,但我会将这三个组提取为

    (anything)(AM|PM)(number,anything)?(BASEMENT-anything)
    

    在哪里?表示可选组。

        2
  •  2
  •   Philip Potter    14 年前

    好吧,您可以按列号删除日期和basement-foo数据,因为它们总是出现在行中的同一点上。然后,可以基于逗号拆分其余部分。是否需要处理转义逗号,或引号“foo,bar”中的逗号取决于您和您的业务需求。

        3
  •  1
  •   codaddict    14 年前

    你可以做到:

    • 以字符串形式读取整行。
    • 在空格(\s+)上拆分读取行。你应该买5到6件。
    • 第0段、第1段和第2段将是 日期、时间和上午/下午。
    • 检查第3段是否有编号:如果有 然后读下一篇文章作为名字
    • 最后一块是地下室的东西。
    • 把这些片段从字符串转换成 日期,时间,需要的时间。
        4
  •  0
  •   Kilian Foth    14 年前

    找出每行空白字符与非空白字符相邻的列,然后对这些数字进行统计分析:每行或几乎每行出现的数字很可能是字段边界。

    类似地,对于与字母相邻的标点符号,但一般来说,不可能猜测a-或a是否意味着要分隔字段。如果它出现在每一行的同一位置,它可能是一个分隔符,但在诸如d-fl r-tx d-ny之类的列表中,它可能不是。因此,对于任意数据不可能有完全自动的解决方案。

        5
  •  0
  •   Mihir Mathuria    14 年前

    由于每个字段都是非常不同的(至少在上面粘贴的示例中如此),因此可以执行以下操作:

    1. 将字符串拆分为标记。
    2. 通过regex模式运行标记化数组的每个元素。
        6
  •  -2
  •   Jonathan Holloway    14 年前

    你可以使用 Strtokenizer 从commons lang并指定要拆分的多个分隔符:

    有许多内置类型通过 StrMatcher .

    StrTokenizer(char[] input, StrMatcher delim) 
    

    例如

    StrMatcher delims = StrMatcher.charSetMatcher(new char[] {' ', ',', '\n'});
    StrTokenizer str = new StrTokenizer(match.toString(), delims);
    while (str.hasNext()) {
        System.out.println("Token:[" + str.nextToken() + "]");
    }
    

    将给出(从上面的示例中):

    Token:[3/3/2010]
    Token:[11:00:46]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:04:04]
    Token:[AM]
    Token:[2]
    Token:[YaserAlNaqeb]
    Token:[BASEMENT-OUT]
    Token:[3/3/2010]
    Token:[11:04:06]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:04:18]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:14:32]
    Token:[AM]
    Token:[4]
    Token:[Dhileep]
    Token:[BASEMENT-OUT]
    Token:[3/3/2010]
    Token:[11:14:34]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:14:41]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:15:33]
    Token:[AM]
    Token:[4]
    Token:[Dhileep]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:15:42]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:15:42]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:30:22]
    Token:[AM]
    Token:[34]
    Token:[KumarRaju]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:31:28]
    Token:[AM]
    Token:[39]
    Token:[Eldrin]
    Token:[BASEMENT-OUT]
    Token:[3/3/2010]
    Token:[11:31:31]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:31:39]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:32:38]
    Token:[AM]
    Token:[39]
    Token:[Eldrin]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:32:47]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:32:47]
    Token:[AM]
    Token:[BASEMENT-IN]
    Token:[3/3/2010]
    Token:[11:33:26]
    Token:[AM]
    Token:[34]
    Token:[KumarRaju]
    Token:[BASEMENT-OUT]
    Token:[3/3/2010]
    Token:[11:33:28]
    Token:[AM]
    Token:[BASEMENT-IN]