【问题标题】:python - asn1 parsed text to jsonpython - asn1 将文本解析为 json
【发布时间】:2019-12-19 00:54:11
【问题描述】:

有了这个link给出的文字,需要提取数据如下

  1. 每条记录以YYYY Mmm dd hh:mm:ss.ms开头,例如2019 Aug 31 09:17:36.550
  2. 每条记录都有一个标题,从上面的第 1 行开始,以空行结束
  3. 记录数据包含在Interpreted PDU:下面的行中
  4. 感兴趣的记录是记录标题第一行有0xB821 NR5G RRC OTA Packet -- RRC_RECONFIG的记录

是否可以将上面#3 以下的选定记录标题和文本提取为嵌套 json 数组,格式如下 - 为简洁起见,确实需要将整个文本数据作为 JSON。

data = [{"time": "2019 Aug 31  09:17:36.550", "PDU Number": "RRC_RECONFIG Message", "Physical Cell ID": 0, "rrc-TransactionIdentifier": 1, "criticalExtensions rrcReconfiguration": {"secondaryCellGroup": {"cellGroupId": 1, "rlc-BearerToAddModList": [{"logicalChannelIdentity": 1, "servedRadioBearer drb-Identity": 2, "rlc-Config am": {"ul-AM-RLC": {"sn-FieldLength": "size18", "t-PollRetransmit": "ms40", "pollPDU": "p32", "pollByte": "kB25", "maxRetxThreshold": "t32"}, "dl-AM-RLC": {"sn-FieldLength": "size18", "t-Reassembly": "ms40", "t-StatusProhibit": "ms20"}}}]}}  }, next records data here]

请注意,输入文本是 3GPP 38.331 第 6.3.2 节中 ASN1 数据规范的解析输出。我不确定普通的 python 文本解析是处理这个问题的正确方法,还是应该使用 asn1tools library 之类的东西?如果是这样,使用此数据的示例会有所帮助。

【问题讨论】:

  • 我相信你可以使用一些正则表达式,虽然它可能不是世界上最好的主意。
  • 您链接的文件中的 ASN.1 数据采用文本表示形式。要使用 asn1tools 库,它必须支持该符号,而不是任何标准编码规则(BER、PER、OER、JER、XER)。我不知道它是否这样做,但我会感到惊讶。
  • 这个问题非常详细,但不包括你自己解决它的尝试和遇到的困难:)

标签: python text-parsing asn.1


【解决方案1】:

不幸的是,不太可能有人会直接回答您的问题(这与 How to extract data from asn1 data file and load it into a dataframe? 非常相似)

您的链接文本显然是一个日志文件,其中使用 ASN.1 值表示法使消息易于阅读。因此,试图从它们的文本形式中解码这些消息是不寻常的,你可能不会找到相应的工具。

理论上,通用方法应该是这个:

  1. 收集用于创建 ASN.1 消息的 ASN.1 定义(架构)
  2. 使用 ASN.1 工具(也称为编译器)编译这些定义,以使用您喜欢的语言 (python) 生成对象模型。该工具将提供编码和解码的特定代码......您将使用 ASN.1 值解码器。
  3. 添加您的自定义代码(添加到对象模型或插入 ASN.1 编译器)以编码您的 JSON 对象

如你所见,这是一个很长的镜头(如果这个解释太短或不清楚,我可以扩展)

除非您的任务是重复性的和/或消息数量很大,否则请尝试您已经知道的方法(手动搜索、正则表达式)来搜索日志文件。

如果您想了解创建 ASN.1 工具需要什么,您可以找到一些(数量不多,因为 ASN.1 并不是特别年轻和流行)。查看https://github.com/etingof/pyasn1 (python)

我在 Java 中创建了自己的乐趣,并添加了 ASN.1 值解码器来说明我的答案:https://github.com/yafred/asn1-tool (branch text-asn-value-support)

【讨论】:

    【解决方案2】:

    鉴于您有输入数据的文本表示,您可以查看parse 库。这允许您在字符串中查找模式并将内容分配给变量。

    这里是提取时间、PDU 编号和物理小区 ID 数据字段的示例:

    import parse
    
    with open('w9s2MJK4.txt', 'r') as f:
      input = f.read()
    
    data = []
    pattern = parse.compile('\n{year:d} {month:w} {day:d}  {hour:d}:{min:d}:{sec:d}.{ms:d}{}Physical Cell ID = {pcid:d}{}PDU Number = {pdu:w} {pdutype:w}')
    
    for s in pattern.findall(input):
      record = {}
      record['time'] = '{} {} {} {:02d}:{:02d}:{:02d}.{:03d}'.format(s.named['year'], s.named['month'], s.named['day'], s.named['hour'], s.named['min'], s.named['sec'], s.named['ms'])
      record['PDU Number'] = '{} {}'.format(s.named['pdu'], s.named['pdutype'])
      record['Physical Cell ID'] = s.named['pcid']
      data.append(record)
    

    由于你有一个相当复杂的结构和大量的数据字段,这可能会变得有点麻烦,但我个人更喜欢这种方法而不是正则表达式。也许还有一种更智能的方法来解析日期(不幸的是,它似乎没有库支持的标准格式之一)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多