【问题标题】:Extracting data from text file with regex使用正则表达式从文本文件中提取数据
【发布时间】:2019-04-03 15:59:02
【问题描述】:

尝试使用正则表达式从 txt 文件中提取三个数据列表

文件结构 = 元数据、值(重复)

#
#text
#text
#
9.2318434E-5 -1.3870514E-9 1.0E-4 7.0E-5 9.2318434E-5 9.225606E-5 9.225606E-5 2.5E-4 2.5E-4
9.230842E-5 -1.3756367E-9 1.0E-4 7.0E-5 9.230842E-5 9.225539E-5 9.225539E-5 0.00225 0.00225
9.230592E-5 -1.3935526E-9 1.0E-4 7.0E-5 9.230592E-5 9.2255046E-5 9.2255046E-5 0.00275 0.00275

#
#text
#text
#
9.2318434E-5 -1.3870514E-9 1.0E-4 7.0E-5 9.2318434E-5 9.225606E-5 9.225606E-5 2.5E-4 2.5E-4
9.231593E-5 -1.3816212E-9 1.0E-4 7.0E-5 9.231593E-5 9.225253E-5 9.225253E-5 7.5E-4 7.5E-4
9.230592E-5 -1.3935526E-9 1.0E-4 7.0E-5 9.230592E-5 9.2255046E-5 9.2255046E-5 0.00275 0.00275

#
#text
#text
#
9.2318434E-5 -1.3870514E-9 1.0E-4 7.0E-5 9.2318434E-5 9.225606E-5 9.225606E-5 2.5E-4 2.5E-4
9.231593E-5 -1.3816212E-9 1.0E-4 7.0E-5 9.231593E-5 9.225253E-5 9.225253E-5 7.5E-4 7.5E-4
9.231343E-5 -1.3962527E-9 1.0E-4 7.0E-5 9.231343E-5 9.225581E-5 9.225581E-5 0.00125 0.00125

我一直在尝试以下

with open(file) as newfile:
    data = re.findall(r'^([#][\n][0-9])[\s\S]*([\n][\n])$', newfile.read())

每个数据块都以 #\n[0-9] 开头并以 \n\n 结尾,然后我需要在开头和结尾之间取每个字符,因此是 [\s\S]*。似乎没有任何帮助会很好。

【问题讨论】:

  • 我不明白你是想要完整的 3 行还是这 3 行中的每个数字?
  • 我希望输出是一个包含三个元素的列表,其中包含一个包含该部分中所有数字的字符串,即 mylist = ["numbers\n numbers\n numbers\n", "numbers\n numbers \n 数字\n", "数字\n 数字\n 数字\n"]
  • 感谢所有工作人员

标签: python regex


【解决方案1】:

附带说明,您无需将所有内容都包含在 [] 中。

查看使用中的正则表达式here

^(?<=#\n)\d[^#]*$
  • ^ 在行首断言位置
  • (?&lt;=#\n) 正向后视确保前面的内容匹配 # 后跟换行符 \n
  • \d 匹配一个数字
  • [^#]* 匹配除 # 之外的任何字符任意次数(贪婪,因此它会尝试匹配尽可能多的字符 - 直到到达另一个 #
  • $ 在行尾断言位置

或者,非常简单,您可以使用 ^\d.*,如 here 所示。

  • ^ 在行首断言位置
  • \d 匹配一个数字
  • .* 匹配任意字符(行终止符除外)任意次数

【讨论】:

    【解决方案2】:

    你可以使用:

    import re
    with open("file.txt") as f:
        t = f.read().strip()
    
    lists = []
    m = re.findall(r"^[\d.E\s-]+$", t, re.MULTILINE) # 45 steps
    for x in m:
        a = [float(x) for x in " ".join(x.strip().split("\n")).split()]
        lists.append(a)
    
    print(lists)
    

    输出:

    [[9.2318434e-05, -1.3870514e-09, 0.0001, 7e-05, 9.2318434e-05, 9.225606e-05, 9.225606e-05, 0.00025, 0.00025, 9.230842e-05, -1.3756367e-09, 0.0001, 7e-05, 9.230842e-05, 9.225539e-05, 9.225539e-05, 0.00225, 0.00225, 9.230592e-05, -1.3935526e-09, 0.0001, 7e-05, 9.230592e-05, 9.2255046e-05, 9.2255046e-05, 0.00275, 0.00275], [9.2318434e-05, -1.3870514e-09, 0.0001, 7e-05, 9.2318434e-05, 9.225606e-05, 9.225606e-05, 0.00025, 0.00025, 9.231593e-05, -1.3816212e-09, 0.0001, 7e-05, 9.231593e-05, 9.225253e-05, 9.225253e-05, 0.00075, 0.00075, 9.230592e-05, -1.3935526e-09, 0.0001, 7e-05, 9.230592e-05, 9.2255046e-05, 9.2255046e-05, 0.00275, 0.00275], [9.2318434e-05, -1.3870514e-09, 0.0001, 7e-05, 9.2318434e-05, 9.225606e-05, 9.225606e-05, 0.00025, 0.00025, 9.231593e-05, -1.3816212e-09, 0.0001, 7e-05, 9.231593e-05, 9.225253e-05, 9.225253e-05, 0.00075, 0.00075, 9.231343e-05, -1.3962527e-09, 0.0001, 7e-05, 9.231343e-05, 9.225581e-05, 9.225581e-05, 0.00125, 0.00125]]
    

    演示:

    【讨论】:

      【解决方案3】:

      如果您愿意,您也可以完全不使用正则表达式来解决这个问题。由于您只想读取不以符号# 开头的行,因此您可以从文件中读取行并检查它们是否以# 开头。然后剥离线并将其从间距中拆分以获取所有数字作为字符串。

      这是一个使用列表推导的示例:

      numbers = []
      with open(file) as newfile:
          numbers += [number for line in newfile.readlines() if not line.startswith('#') for number in line.strip().split()]
      newfile.close()
      print(numbers) # list of all the numbers as strings
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-29
        • 1970-01-01
        • 2017-10-08
        相关资源
        最近更新 更多