问题描述
|
我的一个朋友说,如果我使用的正则表达式过长,则可能是该工作的错误工具。这里有什么更好的方法来解析此文本的想法吗?我有一个正则表达式,可以将所有内容返回一个数组,我可以轻松地将其分块,但是如果有另一种更简单的方法,我真的很想看看。
外观如下:
2 AB 123A 01JAN M ABCDEF AA1 100A 200A 02JAN T /ABCD /E
这是一个分解:
2
是行号,范围从1
一直到99
。如果由于格式而看不到,则空格字符前面的数字小于10。
空格可能会或可能不会被“ 4”代替
“ 5”是数据的重要单位(UOD)。
AB
之前可能是another7ѭ,这是另一个重要的UOD。
123
是重要的UOD。范围从1
(前置4个空格)到99999
。
A
是重要的UOD。
01JAN
是一天/一个月的组合,我需要提取两个UOD。
M
是日名的缩写。这可能是介于1
和7
之间的数字。
ABC
是重要的UOD。
DEF
是重要的UOD。
DEF
之后的空格可能是*
AA1
可以是零个字符,也可以是5个字符。不重要。
100A
是时间戳,但可以采用1300
格式。当PM中的时间是ѭ25或P
时,ѭ11可能是ѭ24。
然后,我们看到另一个时间戳。
下一个日期部分可能不存在,例如,这是有效的:
93*DE/QQ51234 30APR J QWERTY*QQ0 1250 0520 /ABCD*ASDFAS /E
出现“ѭ28”的数据与应用程序无关,但是,这可能是第二个日期戳出现的地方。前斜杠可能是其他东西(例如字母)。
注意:
它不是由空间来界定的,身体的某些部分会碰到其他部分。字符位置仅对列表中的前两个或三个项目准确
我认为我没有遗漏任何内容,但是,如果有比编写正则表达式更容易的方法来解析这样的字符串,请告诉我。
解决方法
对于正则表达式而言,这是一项完美的任务。文本不包含嵌套,并且您要匹配的项目非常容易单独处理。
大多数正则表达式语法都具有29位扩展标志或模式,该标志或模式允许使用空格和注释来提高可读性。例如:
$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\';
等等。
,正则表达式对于该应用程序来说似乎不错,但是出于简单性和可读性,您可能希望将其拆分为多个正则表达式(每个字段一个),以便人们可以更轻松地了解正则表达式的哪个部分对应于哪个变量。
,您总是可以手动编写自己的解析器,但这将比正则表达式多行代码。但是,对于读者而言,代码行可能更简单。
,只需编写一个逐行处理它的自定义解析器即可。似乎所有内容都位于固定位置,而不是用空格/逗号分隔,因此只需将它们用作所需索引即可:
line_number = int(line_text[0:1])
ab_unit = line_text[3:4]
...
如果确实是用空格分隔的,则只需在每行“ 32”处进行解析,然后对每行进行解析,并在适当的地方将每个块拆分为多个组成部分。