代码之家  ›  专栏  ›  技术社区  ›  Laxmikant

根据子字符串索引查找内容

  •  1
  • Laxmikant  · 技术社区  · 6 年前

    下面的代码根据文件中出现的子字符串(我在这里说关键字)以及与之相关的文本,从文件中提取行:

    from itertools import count
    
    def find_content_blocks_by_keywords(lines, keywords):
        keyword_indexes = sorted([i for i, line in zip(count(), lines) for 
        keyword in keywords if re.search(keyword, line)])  
        return [lines[i:j] for i, j in zip([0]+keyword_indexes, keyword_indexes+[None])]
    

    这是我的示例文本文件

    keywords = ['Total item value', 'Total weight', 'Total volume']
    lines = ['Total item value RSX 05,018.88\n',
      'Total weight 90,969 EUR\n',
      'Total volume -97.93 X3 Sca.\n',
      '197.939 X3 Sca.']
    

    要提取的子字符串及其值

    result = find_content_blocks_by_keywords(lines, keywords):
    

    样本结果:

    [[],
     ['Total item value RSX 05,018.88\n'],
     ['Total weight 90,969 EUR\n'],
     ['Total volume -97.93 X3 Sca.\n', '197.939 X3 Sca.']]
    

    我们可以通过使用 re.findall 或任何其他 re 直接用什么方法?

    由于内容在我的文件中不是固定的,所以无法使用某些正则表达式来提取它。逻辑是,找到关键字并获取它前面的所有内容,除非出现下一个关键字。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Wiktor Stribiżew    6 年前

    以下是我建议的解决方案:

    from itertools import count
    import re
    
    keywords = ['Total item value', 'Total weight', 'Total volume']
    lines = ['Total item value RSX 05,018.88\n',
      'Total weight 90,969 EUR\n',
      'Total volume -97.93 X3 Sca.\n',
      '197.939 X3 Sca.']
    
    pat = r'(?m)^(?:{0}).*(?:[\r\n]+(?!(?:{0})).*)*'.format("|".join([re.escape(x) for x in keywords]))
    print(re.findall(pat, "\n".join(lines)))
    

    输出 Python demo :

    ['Total item value RSX 05,018.88\n', 'Total weight 90,969 EUR\n', 'Total volume -97.93 X3 Sca.\n\n197.939 X3 Sca.']
    

    模式描述

    • (?m) - re.MULTILINE 改性剂制造 ^ 匹配行首
    • ^ -起跑线
    • (?:{0}) -a non-capturing group 其中将包含以下列表中列出的备选方案: | alternation operator (例如:。 Total item value|Total weight|Total volume )
    • .* -除LF以外的任何0+字符(该行的其余部分)
    • (?:[\r\n]+(?!(?:{0})).*)* -0次或以上重复:
      • [\r\n]+(?!(?:{0})) -1个或多个LF或/和CR符号( [\r\n]+ )没有任何 keywords 项目
      • .* -剩下的部分