1

从每个字段之间没有明确分隔符(分隔符)的每一行中提取每个字段的最佳方法是什么?

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

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 可以为空(但在所有情况下都应确认其存在)
  • 空格的数量可以改变
  • 最后一句话可以改变
4

6 回答 6

2

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

于 2010-03-04T07:30:31.053 回答
1

你可以做:

  • 将整行读取为字符串。
  • 在空格(\s+)上拆分读取行。你应该得到 5 或 6 件。
  • piece0、piece1 和 piece2 将是日期、时间和 AM/PM。
  • 检查piece3是否有编号:如果是,则将下一件读作名称
  • 最后一块是地下室的东西。
  • 根据需要将字符串从字符串转换为日期、时间、整数。
于 2010-03-04T07:30:47.493 回答
1

对我来说似乎有 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 直到 [AM|PM]

MF2 号码,除地下室以外的任何号码-*

MF3 地下室-*

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

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

在哪里?表示可选组。

于 2010-03-04T08:57:56.050 回答
0

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

与字母相邻的标点符号类似,但通常无法猜测 a - 或 a , 是否用于分隔字段。如果它出现在每一行中的相同位置,它可能是一个分隔符,但在诸如 D-FL R-TX D-NY 之类的事物列表中它可能不是。因此,对于任意数据,不可能有全自动的解决方案。

于 2010-03-04T07:33:49.703 回答
0

由于每个字段都非常不同(至少在您上面粘贴的示例中),您可以这样做:

  1. 将字符串拆分为标记。
  2. 通过正则表达式模式运行标记化数组的每个元素。
于 2010-03-04T07:34:35.393 回答
-2

您可以使用Commons Lang 中的Strtokenizer并指定多个分隔符进行拆分:

有许多通过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]
于 2010-03-04T07:29:00.883 回答