格式不同时如何使用 re return 字符串?
how to return string with re when formatting is different?
问题介绍
我在 .txt 文件中有输入,我想 'extract' 给定速度时的值。
输入的格式为: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
[...]
我做了什么
当请求速度时,我已经为 return 值编写了一段代码:
def values(input,velocity):
return re.findall("\n"+str(velocity)+".*",input)[-1][1:]
它有效 "backwards" 因为我想忽略输入的第一行 (16\t1\t0\n),这样如果我调用:
>>>values('inputs.txt',16)
>>>16.0000\t0.5646\t14.3658\t1.4782\n
但它有一个大问题:如果我为 1 调用函数,它 return 的值为 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
[...]
而且,我的解决方案当然行不通
那么,是否有适合两种输入的模式?
感谢您的帮助。
P.S。我有一个使用函数 split('\n')
和索引的解决方案,但我想用 re 库解决它:
def values(input,velocity):
return input.split('\n)[velocity+1] #+1 to avoid first row
您可以使用积极的展望来检查您的速度之后是否有一个句点或一个制表符。这将阻止你在没有硬编码的情况下选择更多的数字,必须有 .0
。这意味着速度 1 将能够匹配 1 或 1.xxxxx
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']
问题介绍
我在 .txt 文件中有输入,我想 'extract' 给定速度时的值。 输入的格式为: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
[...]
我做了什么
当请求速度时,我已经为 return 值编写了一段代码:
def values(input,velocity):
return re.findall("\n"+str(velocity)+".*",input)[-1][1:]
它有效 "backwards" 因为我想忽略输入的第一行 (16\t1\t0\n),这样如果我调用:
>>>values('inputs.txt',16)
>>>16.0000\t0.5646\t14.3658\t1.4782\n
但它有一个大问题:如果我为 1 调用函数,它 return 的值为 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
[...]
而且,我的解决方案当然行不通
那么,是否有适合两种输入的模式?
感谢您的帮助。
P.S。我有一个使用函数 split('\n')
和索引的解决方案,但我想用 re 库解决它:
def values(input,velocity):
return input.split('\n)[velocity+1] #+1 to avoid first row
您可以使用积极的展望来检查您的速度之后是否有一个句点或一个制表符。这将阻止你在没有硬编码的情况下选择更多的数字,必须有 .0
。这意味着速度 1 将能够匹配 1 或 1.xxxxx
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']