【问题标题】:How to filter the specific entries within a with a specific pattern over certain value? [duplicate]如何在特定值上过滤具有特定模式的特定条目? [复制]
【发布时间】:2020-01-31 09:48:06
【问题描述】:

我有一个包含以下信息的数据文件: 我有兴趣只检索模式所在的条目

len:XXXX 大于 200

TY_DN106_c0_g2::TY_DN106_c0_g2_i1::g.1::m.1 type:internal len:123 gc:universal TY_DN106_c0_g2_i1:1-366(+) TY_DN106_c0_g2::TY_DN106_c0_g2_i1::g.2::m.2 type:internal len:213 gc:universal TY_DN106_c0_g2_i1:366-1(-) TY_DN108_c0_g1::TY_DN108_c0_g1_i1::g.3::m.3 type:5partial len:513 gc:universal TY_DN108_c0_g1_i1:3-341(+)

我怎么能用 Python 或其他脚本语言做到这一点??

【问题讨论】:

  • 什么是输入格式?您需要获取包含 len:xxx > 200 的整行?
  • 它是文本文件,我需要所有具有 lenxxx>200 的条目
  • 文本在一行还是逐行分隔?通过条目,您的意思是从..到...的文本?
  • 每个条目由一个新行分隔,每个条目都以“TY”开头
  • @TCFPHCDG 你能提供一个你想要得到什么的例子吗?

标签: python regex search filtering


【解决方案1】:

您可以使用len:([2-9]\d{2}|[1-9]\d{3,}) 正则表达式来获取您需要的匹配项。

如果要匹配整行,请使用:^.*len:([2-9]\d\d|[1-9]\d{3,}).*$


正则表达式解释

表达式的第一部分:len: 匹配字符 'len:' 字面意思。

之后,在第一个捕获组中,我们有 2 个备选方案。

第一个选项:[2-9]\d{2} 匹配 2 到 9 之间的数字,后跟任意两位数字,从而涵盖从 200 到 999 的所有数字。

第二个选项:[1-9]\d{3,} 匹配所有以数字 1 到 9 开始,后跟 3 个其他数字的字符,从而覆盖从 1000 到 inf 的所有整数,省略以 0 开头的数字字符。

【讨论】:

    【解决方案2】:

    对于 data.txt 文件中的数据,如下所示:

    TY_DN106_c0_g2::TY_DN106_c0_g2_i1::g.1::m.1 type:internal len:123 gc:universal
    TY_DN106_c0_g2_i1:1-366(+)
    TY_DN106_c0_g2::TY_DN106_c0_g2_i1::g.2::m.2 type:internal len:213 gc:universal
    TY_DN106_c0_g2_i1:366-1(-)
    TY_DN108_c0_g1::TY_DN108_c0_g1_i1::g.3::m.3 type:5partial len:513 gc:universal
    TY_DN108_c0_g1_i1:3-341(+)
    

    使用正则表达式: 1.找到合适的线路 2.提取号码 3.比较数字和条件

    import re
    
    data = open('data.txt', 'r').readlines()
    
    for line in data:
        proper_row = re.findall('len:\d+', line.strip())
        if len(proper_row) > 0:
            number = re.findall('\d+', proper_row[0])[0]
            if int(number) > 200:
                print(line.strip())
    

    输出:

    TY_DN106_c0_g2::TY_DN106_c0_g2_i1::g.2::m.2 type:internal len:213 gc:universal
    TY_DN108_c0_g1::TY_DN108_c0_g1_i1::g.3::m.3 type:5partial len:513 gc:universal
    

    【讨论】:

      【解决方案3】:

      这是一个例子:

      import re
      
      
      file_path = 'file.txt'
      pattern = r'len:\d{3,}'
      
      with open(file_path, 'r', encoding='utf-8') as f:
          for line in f.readlines():
              if re.search(pattern, line):
                  if int(re.search(pattern, line)[0].split(':')[1]) > 200:
                      print(line)
      

      如果你不想将结果写入新文件,试试这个:

      import re
      
      
      file_path = 'file.txt'
      new_file_path = 'new_file.txt'
      pattern = r'len:\d{3,}'
      
      with open(file_path, 'r', encoding='utf-8') as f1:
          with open(new_file_path, 'w', encoding='utf-8') as f2:
              for line in f1.readlines():
                  if re.search(pattern, line):
                      if int(re.search(pattern, line)[0].split(':')[1]) > 200:
                          f2.write(line)
      

      这是@Henry Harutyunyan 的正则表达式示例:

      import re
      
      
      file_path = 'file.txt'
      pattern = r'len:([2-9]\d{2}|[1-9]\d{3,})'
      
      with open(file_path, 'r', encoding='utf-8') as f1:
          for line in f1.readlines():
              if re.search(pattern, line):
                  print(line)
      

      【讨论】:

      • 可以用单个正则表达式而不需要拆分和检查
      • 是的,你可以通过@HenryHarutyunyan 学习正则表达式
      • 它只会打印第一次出现的“模式”并关闭文件。
      • 如果我们需要找到所有具有这种模式的行怎么办
      • import re infile = "/Users/tcfh/Desktop/test_length_filter" outfile="/Users/tcfh/Desktop/test_length_filter_out" pat = r'len:([2-9]\d{2 } | [1-9]\d{3,})' with open(infile, 'r') as f1, open(outfile, 'w') as f2: for seqhead in (f1): if re.search( pat, seqhead): seqhd = seqhead seq= (next(f1, '').strip()) blc = (seqhd + seq) f2.write (blc)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-18
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2017-01-29
      相关资源
      最近更新 更多