首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仅从文本中提取json/dict或获取匹配括号内的文本

仅从文本中提取json/dict或获取匹配括号内的文本
EN

Stack Overflow用户
提问于 2019-04-18 00:22:14
回答 1查看 34关注 0票数 0

我正在尝试从可以包含各种文本的大文本文件中只获取json的一部分。

我通过尝试匹配/获取括号{}之间的所有文本来解决这个问题,但我仍然相信应该有更好的方法来做到这一点,所以请给我一些建议。也许是拆分文件,然后尝试解析它,或者是我遗漏了一些库?我必须对大于200MB的文件执行此操作。

代码语言:javascript
复制
citaj="""
..bla....bla....bla...bla....bla....
supportedBandCombination-r10{
  BandCombinationParameters-r10{
    BandParameters-r10{
      bandEUTRA-r101,
      bandParametersUL-r10{
        CA-MIMO-ParametersUL-r10{
          ca-BandwidthClassUL-r10a
        }
      },
      bandParametersDL-r10{
        CA-MIMO-ParametersDL-r10{
          ca-BandwidthClassDL-r10a,
          supportedMIMO-CapabilityDL-r10twoLayers
        }
      }
    }
  },
  BandCombinationParameters-r10{
    BandParameters-r10{
      bandEUTRA-r103,
      bandParametersUL-r10{
        CA-MIMO-ParametersUL-r10{
          ca-BandwidthClassUL-r10a
        }
      },
      bandParametersDL-r10{
        CA-MIMO-ParametersDL-r10{
          ca-BandwidthClassDL-r10a,
          supportedMIMO-CapabilityDL-r10twoLayers
        }
      }
    }
  }
}
..bla....bla....bla...bla....bla....
..bla....bla....bla...bla....bla...."""


import re
string = open("citaj.txt","r").read()
stack = 0
startIndex = None
results = []
indx = [m.start() for m in re.finditer('BandCombinationParameters', string)]
for jota in indx:
    for i, c in enumerate(string[jota:]):  
        if c == '{':
            if stack == 0:
                startIndex = i + 1 # string to extract starts one index later
            # push to stack
            stack += 1
        elif c == '}':
            # pop stack
            stack -= 1

            if stack == 0:
                results.append(string[startIndex:i])
print(results)

输出应为

代码语言:javascript
复制
results[0]=
BandCombinationParameters-r10{
  BandParameters-r10{
    bandEUTRA-r101,
    bandParametersUL-r10{
      CA-MIMO-ParametersUL-r10{
        ca-BandwidthClassUL-r10a
      }
    },
    bandParametersDL-r10{
      CA-MIMO-ParametersDL-r10{
        ca-BandwidthClassDL-r10a,
        supportedMIMO-CapabilityDL-r10twoLayers
      }
    }
  }
}
results[1]=
BandCombinationParameters-r10{
  BandParameters-r10{
    bandEUTRA-r103,
    bandParametersUL-r10{
      CA-MIMO-ParametersUL-r10{
        ca-BandwidthClassUL-r10a
      }
    },
    bandParametersDL-r10{
      CA-MIMO-ParametersDL-r10{
        ca-BandwidthClassDL-r10a,
        supportedMIMO-CapabilityDL-r10twoLayers
      }
    }
  }
}
EN

回答 1

Stack Overflow用户

发布于 2019-05-05 23:36:57

由于您使用的是Python,因此您可能会发现pyparsing是为这种格式(不是JSON,btw)创建解析器原型的一种快速方法:

代码语言:javascript
复制
src = """
supportedBandCombination-r10{
  BandCombinationParameters-r10{
    BandParameters-r10{
      bandEUTRA-r101,
      bandParametersUL-r10{
        CA-MIMO-ParametersUL-r10{
          ca-BandwidthClassUL-r10a
        }
      },
      bandParametersDL-r10{
        CA-MIMO-ParametersDL-r10{
          ca-BandwidthClassDL-r10a,
          supportedMIMO-CapabilityDL-r10twoLayers
        }
      }
    }
  },
  BandCombinationParameters-r10{
    BandParameters-r10{
      bandEUTRA-r103,
      bandParametersUL-r10{
        CA-MIMO-ParametersUL-r10{
          ca-BandwidthClassUL-r10a
        }
      },
      bandParametersDL-r10{
        CA-MIMO-ParametersDL-r10{
          ca-BandwidthClassDL-r10a,
          supportedMIMO-CapabilityDL-r10twoLayers
        }
      }
    }
  }
}"""

import pyparsing as pp

LBRACE,RBRACE = map(pp.Suppress, "{}")
term = pp.Word(pp.alphas, pp.alphanums+'-')

term_group = pp.Forward()
term_group <<= pp.Group(term + pp.Group(LBRACE 
                                         + pp.delimitedList(term_group | term) 
                                         + RBRACE))

term_group.parseString(src).pprint()

打印

代码语言:javascript
复制
[['supportedBandCombination-r10',
  [['BandCombinationParameters-r10',
    [['BandParameters-r10',
      ['bandEUTRA-r101',
       ['bandParametersUL-r10',
        [['CA-MIMO-ParametersUL-r10', ['ca-BandwidthClassUL-r10a']]]],
       ['bandParametersDL-r10',
        [['CA-MIMO-ParametersDL-r10',
          ['ca-BandwidthClassDL-r10a',
           'supportedMIMO-CapabilityDL-r10twoLayers']]]]]]]],
   ['BandCombinationParameters-r10',
    [['BandParameters-r10',
      ['bandEUTRA-r103',
       ['bandParametersUL-r10',
        [['CA-MIMO-ParametersUL-r10', ['ca-BandwidthClassUL-r10a']]]],
       ['bandParametersDL-r10',
        [['CA-MIMO-ParametersDL-r10',
          ['ca-BandwidthClassDL-r10a',
           'supportedMIMO-CapabilityDL-r10twoLayers']]]]]]]]]]]

但是,pyparsing并不快,并且需要相当长的时间来筛选您的200MB文件。

Pyparsing也不擅长流式处理,但它希望一次解析整个字符串。对于您的200MB文件,这可能实用,也可能不实用。您可以尝试一次读取一行,直到得到一个可解析的结构,然后解析它并继续前进。或者一次读取100行,直到得到一个可解析的结构,然后解析它,保留未解析的部分,然后再读取100行。但在这一切中,性能限制因素将是解析器,因此在尝试构建可成功解析的字符串时,您需要尽量减少错误解析的数量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55732127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档