我的一位朋友说,如果我使用的正则表达式太长,那可能是错误的工具。有什么想法可以更好地解析这个文本吗?我有一个正则表达式,它将所有内容都返回到一个数组,我可以很容易地将其缩小,但如果有另一种更简单的方法,我真的很想看到它。
这是它的样子:
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
。如果PM中的时间为A
或N
,则1200
可能为P
。
然后我们看到另一个时间戳。
下一个日期部分可能不存在,例如,这是有效的:
93*DE/QQ51234 30APR J QWERTY*QQ0 1250 0520 /ABCD*ASDFAS /E
出现/ABCD*ASDFAS /E
的数据与应用程序无关,但这是第二个日期戳可能出现的位置。前斜线可能是其他东西(例如字母)。
注意:
它不是空间划分的,身体的某些部分会遇到其他部分。字符位置仅对列表中的前两个或三个项目准确
我认为我没有留下任何东西,但是,如果有一种更简单的方法来解析这样的字符串而不是写一个正则表达式,请告诉我。
答案 0 :(得分: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';
等等。
答案 1 :(得分:2)
这个应用程序的正则表达式似乎很好,但为了简单和可读性,您可能希望将其拆分为多个正则表达式(每个字段一个),以便人们可以更轻松地跟随正则表达式的哪一部分对应于哪个变量。
答案 2 :(得分:1)
您总是可以手动编写自己的解析器代码,但这将是比正则表达式更多的代码行。但是,对于读者来说,代码行可能更容易理解。
答案 3 :(得分:0)
只需编写一个逐行处理它的自定义解析器。似乎所有东西都处于固定位置而不是空格/逗号分隔,所以只需将它们作为索引就可以满足您的需求:
line_number = int(line_text[0:1])
ab_unit = line_text[3:4]
...
如果它确实以空格分隔,只需split()
每一行,然后解析每一行,在适当的时候将每个块拆分成组件部分。