как вернуть строку с ре, когда форматирование отличается? - PullRequest
1 голос
/ 27 апреля 2020

Введение в проблему

У меня есть входные данные в файле .txt, и я хочу «извлечь» значения, когда задана скорость. Входные данные имеют вид: скорость \ 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

1 Ответ

0 голосов
/ 27 апреля 2020

Вы можете использовать положительный взгляд вперед, чтобы проверить, что после вашей скорости есть либо точка, либо табуляция. Это остановит вас при наборе дальнейших номеров без жесткого кодирования, должно быть .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']
...