1

我的一个朋友说,如果我使用的正则表达式太长,它可能是适合这项工作的错误工具。这里有什么更好的方法来解析这个文本吗?我有一个正则表达式,可以将所有内容返回到一个数组中,我可以轻松地将其分块,但如果有另一种更简单的方法,我真的很想看到它。

这是它的样子:

 2 AB 123A 01JAN M ABCDEF AA1   100A  200A  02JAN T /ABCD /E    

这是一个细分:

  • 2是行号,这些范围从1一直到99. 如果由于格式化而看不到,则在小于 10 的数字前有一个空格字符。

    该空间可能会或可能不会被替换*

  • AB是重要的数据单位(UOD)。

    AB可以在前面加上/CD另一个重要的 UOD。

  • 123是一个重要的UOD。它的范围可以从1(前面加上 4 个空格)到99999.

  • A是一个重要的UOD。

  • 01JAN是天/月组合,我需要提取两个 UOD。

  • M是日期名称的缩写形式。这可能是 和 之间的1数字7

  • ABC是一个重要的UOD。

  • DEF是一个重要的UOD。

    后面的空格DEF可能是*

  • AA1可能是零个字符,也可能是 5 个。这并不重要。

  • 100A是时间戳,但可能格式为1300. A可能是在下午的N时间1200或时间。P

  • 然后我们看到另一个时间戳。

  • 下一个日期部分可能不存在,例如,这是有效的:

    93*DE/QQ51234 30APR J QWERTY*QQ0   1250   0520 /ABCD*ASDFAS /E             
    
  • 出现的数据/ABCD*ASDFAS /E与应用程序无关,但是,这是第二个日期戳可能出现的地方。前斜线可能是其他东西(例如字母)。

注意:
它不是空格分隔的,身体的某些部位会碰到其他部位。字符位置仅对列表中的前两个或三个项目准确

我认为我没有遗漏任何内容,但是,如果有比编写正则表达式更简单的方法来解析这样的字符串,请告诉我。

4

4 回答 4

6

这是正则表达式的完美任务。文本不包含嵌套,并且您匹配的项目非常简单,可以单独获取。

大多数正则表达式语法都有一个x倾向标志或模式,允许空格和注释以提高可读性。例如:

$regex = '@
    # 2 is the line number, these range from 1 all the way to 99.
    # There is a space character prepending numbers less than 10.
    # The space may or may not be replaced by an *.
    [ *]\d|\d\d
    \s

    # AB is an important unit of data (UOD).
    # AB may be prepended by /CD which is another important UOD.
    (/CD)?AB
    \s

    # 123 is an important UOD. It can range from 1 (prepended by 4 spaces)
    # to 99999.
    \s{4}\d{1}|\s{3}\d{2}|\s{2}\d{3}|\s{1}\d{4}|\d{5}
@x';

等等。

于 2011-04-15T20:10:27.177 回答
2

一个正则表达式似乎适合这个应用程序,但为了简单和可读性,您可能希望将其拆分为多个正则表达式(每个字段一个),以便人们可以更轻松地了解正则表达式的哪个部分对应于哪个变量。

于 2011-04-15T20:11:42.317 回答
1

您总是可以手动编写自己的解析器,但这将比正则表达式更多的代码行。然而,对于读者来说,这些代码行可能更容易理解。

于 2011-04-15T20:01:00.103 回答
0

只需编写一个自定义解析器来逐行处理它。似乎所有内容都处于固定位置而不是空格/逗号分隔,因此只需将它们用作您需要的索引:

line_number = int(line_text[0:1])
ab_unit = line_text[3:4]
...

如果它确实是用空格分隔的,只需split()每一行,然后解析每一行,在适当的地方将每个块拆分为组件部分。

于 2011-04-15T20:00:40.260 回答