在Python中解析具有可变字段大小的字符串

时间:2018-08-08 07:43:14

标签: python

我有这个长度为66的字符串。 Vue.set。直到下一个关键字为止,两个字母(关键字RP000729SP001CT087ET02367EL048TP020DS042MF0220LT9.300000LN4.500000之类的字母)表示下一个是值。

现在,我正在解析字符串,以使两个关键字之间的字节数保持不变,即RPRP之间的000729。下面是要解析的代码。

SP

输出:

msgStr = "RP000729SP001CT087ET02367EL048TP020DS042MF0220LT9.300000LN4.500000"

Ppm = msgStr[msgStr.find("RP")+2:msgStr.find("SP")]
Speed = msgStr[msgStr.find("SP")+2:msgStr.find("CT")]
Coolent_temp = msgStr[msgStr.find("CT")+2:msgStr.find("ET")]
ETime = msgStr[msgStr.find("ET")+2:msgStr.find("EL")]
E_load = msgStr[msgStr.find("EL")+2:msgStr.find("TP")]
Throttle_pos = msgStr[msgStr.find("TP")+2:msgStr.find("DS")]
Distance = msgStr[msgStr.find("DS")+2:msgStr.find("MF")]
MAF = msgStr[msgStr.find("MF")+2:msgStr.find("LT")]
Lat = msgStr[msgStr.find("LT")+2:msgStr.find("LN")]
Lon = msgStr[msgStr.find("LN")+2:]

print Ppm, Speed, Coolent_temp, ETime, E_load, Throttle_pos, Distance, MAF, Lat, Lon

现在,我想收集两个关键字之间是否有任何字节数。示例在下面给出

示例1:

000729 001 087 02367 048 020 042 0220 9.300000 4.500000

预期的输出1:

Example1_msgStr= "RP729SP14CT087ET2367EL48TP20DS42MF0220LT0.000000LN0.000000"

示例2:

729 14 087 2367 48 20 42 0220 0.000000 0.000000

预期的输出2:

Example2_msgStr = "RP72956SP134CT874ET02367EL458TP20DS042MF0220LT53.000LN45.00" 

2 个答案:

答案 0 :(得分:2)

您应该使用正则表达式查找两个字符串之间的可变长度匹配项:

import re
regex = r'RP(\d+)SP'
strings = ['RP729SP14CT087ET2367EL48TP20DS42MF0220LT0.000000LN0.000000',
    'RP72956SP134CT874ET02367EL458TP20DS042MF0220LT53.000LN45.00']
for string in strings:
    match = re.search(regex,string)
    print('Matched:',match.group(1))

在正则表达式中,括号()指定要存储的组,\ d +表示1个或多个数字字符。因此,整个正则表达式RP(\d+)SP将在RP和SP之间找到一个可变长度的数字字符串。

这向您展示了一种情况,您需要遍历定界符(RP,SP,CT等)以捕获所需的所有信息。如果定界符总是以相同的顺序出现,那么您可以构建一个巨大的正则表达式来一次捕获所有组...

答案 1 :(得分:1)

如果要检查定界符之间的字符,可以使用代码,然后将任何变量转换为bool类型。如果字符串不为空,则表示该字符串中包含某些内容,因此返回True。如果字符串为空,则返回False:

    msgStr = 'RP000729SP001CT087ET02367EL048TP020DS042MF0220LT9.300000LN4.500000'

    rpm = msgStr[msgStr.find("RP")+2:msgStr.find("SP")]       # Outputs '000729'
    Speed = msgStr[msgStr.find("SP")+2:msgStr.find("CT")]     # Outputs '001'
    coolent_temp = msgStr[msgStr.find("CT")+2:msgStr.find("ET")] # Outputs '087'
    ETime = msgStr[msgStr.find("ET")+2:msgStr.find("EL")]     # '02367'
    e_load = msgStr[msgStr.find("EL")+2:msgStr.find("TP")]    # '048'
    throttle_pos = msgStr[msgStr.find("TP")+2:msgStr.find("DS")] # '020'
    Distance = msgStr[msgStr.find("DS")+2:msgStr.find("MF")]  # Outputs '042'
    MAF = msgStr[msgStr.find("MF")+2:msgStr.find("LT")]       # Outputs '0220'
    Lat = msgStr[msgStr.find("LT")+2:msgStr.find("LN")]       # Outputs '9.300000'
    Lon = msgStr[msgStr.find("LN")+2:]                        # Outputs '4.500000'

    bool(rpm)           # Outputs True
    bool(Speed)         # Outputs True
    bool(coolent_temp)  # Outputs True
    bool(ETime)         # Outputs True
    bool(e_load)        # Outputs True
    bool(throttle_pos)  # Outputs True
    bool(Distance)      # Outputs True
    bool(MAF)           # Outputs True
    bool(Lat)           # Outputs True
    bool(Lon)           # Outputs True

您可以同时检查几个不为空的字段:

    all_filled = bool(rpm) and bool(Speed) and bool(coolent_temp) and \
    bool(ETime) and bool(e_load) and bool(throttle_pos) and bool(Distance) \
    and bool(MAF) and bool(Lat) and bool(Lon)

设置代码的方式,如果您使用msgStr1进行尝试,则已经获得了所需的分隔:

Example1_msgStr= "RP729SP14CT087ET2367EL48TP20DS42MF0220LT0.000000LN0.000000"
# ... your code ...
print (rpm, Speed, coolent_temp, ETime, e_load, throttle_pos, Distance, MAF, Lat, Lon)
#> 729 14 087 2367 48 20 42 0220 0.000000 0.000000

Example2_msgStr= "RP72956SP134CT874ET02367EL458TP20DS042MF0220LT53.000LN45.00"
# ... your code ...
print (rpm, Speed, coolent_temp, ETime, e_load, throttle_pos, Distance, MAF, Lat, Lon)
#> 72956 134 874 02367 458 20 042 0220 53.000 45.00