regex python正则表达式-如何获取每个组

vaqhlq81  于 2023-01-06  发布在  Python
关注(0)|答案(2)|浏览(174)

我尝试使用python regex获取以"BO_"开头的每个组。(数据来自:https://github.com/commaai/opendbc
原文:

...
BS_:

BU_: XXX CAMERA FRONT_RADAR ADRV APRK

BO_ 53 ACCELERATOR: 32 XXX
 SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
 SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
 SG_ GEAR : 192|3@1+ (1,0) [0|7] "" XXX
 SG_ ACCELERATOR_PEDAL : 40|8@1+ (1,0) [0|255] "" XXX

BO_ 64 GEAR_ALT: 32 XXX
 SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
 SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
 SG_ GEAR : 32|3@1+ (1,0) [0|7] "" XXX

BO_ 69 GEAR: 24 XXX
 SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
 SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
 SG_ GEAR : 44|3@1+ (1,0) [0|7] "" XXX

...
CM_ SG_ 96 BRAKE_PRESSURE "User applied brake pedal pressure. Ramps from computer applied pressure on falling edge of cruise. Cruise cancels if !=0";
CM_ SG_ 101 BRAKE_POSITION "User applied brake pedal position, max is ~700. Signed on some vehicles";
CM_ SG_ 373 PROBABLY_EQUIP "aeb equip?";

我希望捕获BO ID(BO_ ID)位于[53,69]中的BO_块,如下所示:

BO_ 53 ACCELERATOR: 32 XXX
 SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
 SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
 SG_ GEAR : 192|3@1+ (1,0) [0|7] "" XXX
 SG_ ACCELERATOR_PEDAL : 40|8@1+ (1,0) [0|255] "" XXX

BO_ 69 GEAR: 24 XXX
 SG_ CHECKSUM : 0|16@1+ (1,0) [0|65535] "" XXX
 SG_ COUNTER : 16|8@1+ (1,0) [0|255] "" XXX
 SG_ GEAR : 44|3@1+ (1,0) [0|7] "" XXX

有什么建议吗?非常感谢。
到目前为止,我尝试的是1)使用下面的正则表达式捕获BO_和相关SG,但它只捕获了每个BO和第一个SG组。

BO_ (\w+) (\w+) *: (\w+) (\w+)\n (SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)\n)*

1.使用贪婪方法,但它一次捕获了除最后一个事件外的所有BO。

BO_ (\w+) (\w+) *: (\w+) (\w+)((.|\n)*)BO_

此外,为了只选择列表[53,69]中包含数字的BO,我使用了原始的f字符串方法,类似于正则表达式中的rf"{digit}"

iq3niunx

iq3niunx1#

在使用正则表达式解析dbc文件的过程中,我建议您使用像cantools这样的正确解析器:
Python 3中的CAN总线工具。

  • DBCKCD、SYM、ARXML 3和4以及CDD文件解析。
  • CAN消息编码和解码。
  • 简单和扩展信号复用。
  • 诊断DID编码和解码。
  • candump输出解码器。
  • 节点tester _。
  • C源代码生成器。
  • CAN总线监控器。
  • 信号的图形图。
jv4diomz

jv4diomz2#

您可以使用re.DOTALLinline s)和re.MULTILINEinline m)标志轻松捕获带有re.findall的段落。
正则表达式(带内联标志):(?sm)BO_ (?:53|69) .+?^$
用途(选择一项):

re.findall(r"(?sm)BO_ (?:53|69) .+?^$", text)
re.findall(r"BO_ (?:53|69) .+?^$", text, flags=re.DOTALL | re.MULTILINE)

这会延迟捕获从BO_ 53BO_ 69到空白行^$demo)的所有行。

相关问题