首页 > 解决方案 > 格式不同时如何用re返回字符串?

问题描述

问题简介

我在 .txt 文件中有输入,我想在给出速度时“提取”这些值。输入的形式为:velocity\t\val1\t\val2...\tvaln

[...]
16\t1\t0\n
1.0000\t9.3465\t8.9406\t35.9604\n
2.0000\t10.4654\t9.9456\t36.9107\n
3.0000\t11.1235\t10.9378\t37.1578\n
[...]

我做了什么

我编写了一段代码来在请求速度时返回值:

def values(input,velocity):
   return re.findall("\n"+str(velocity)+".*",input)[-1][1:]

它“向后”工作,因为我想忽略输入 (16\t1\t0\n) 的第一行,如果我这样调用:

>>>values('inputs.txt',16)
>>>16.0000\t0.5646\t14.3658\t1.4782\n

但它有一个大问题:如果我调用 1 的函数,它会返回 19.0000 的值

因为我认为所有输入都采用相同的格式,所以我做了一个小修复:

 def values(input,velocity):
   if velocity <= 5: #Because velocity goes to 50
       velocity = str(velocity)+'.0'
   return re.findall("\n"+velocity+".*",input)[-1][1:]

它工作得很好,也许不是最漂亮(或最有效)的方式,但我是初学者。

问题

但是使用这段代码我有一个问题,有时输入有这种形式:

[...]
16\t1\t0\n
1\t9.3465\t8.9406\t35.9604\n
2\t10.4654\t9.9456\t36.9107\n
3\t11.1235\t10.9378\t37.1578\n
[...]

而且,当然我的解决方案不起作用

那么,有没有适合这两种输入的模式?

谢谢您的帮助。

PS我有一个使用函数split('\n')和索引的解决方案,但我想用re库解决它:

def values(input,velocity):    
    return input.split('\n)[velocity+1] #+1 to avoid first row

标签: pythonpython-3.xre

解决方案


您可以使用积极的前瞻性来检查在您的速度之后是否有一个句点或一个标签。这将阻止您在没有硬编码的情况下获取更多的数字.0。这意味着速度 1 将能够匹配 1 或 1.xxxx

import re
from typing import List
def find_by_velocity(velocity: int, data: str) -> List[str]:
    return re.findall(r"\n" + str(velocity) + r"(?=\.|\t).*", data)

data = """16\t1\t0\n1\t9.3465\t8.9406\t35.9604\n2\t10.4654\t9.9456\t36.9107\n3\t11.1235\t10.9378\t37.1578\n16\t1\t0\n1.0000\t9.3465\t8.9406\t35.9604\n2.0000\t10.4654\t9.9456\t36.9107\n3.0000\t11.1235\t10.9378\t37.1578\n"""
print(find_by_velocity(1, data))

输出

['\n1\t9.3465\t8.9406\t35.9604', '\n1.0000\t9.3465\t8.9406\t35.9604']

推荐阅读