Muszę przetworzyć listę prostych ciągów o znanej strukturze, ale uważam, że jest niepotrzebnie niezgrabna. Czuję, że brakuje mi jakiejś sztuczki, może jakiegoś prostego regexu, który uczyniłby to banalnym?Python - łańcuch parse, znana struktura
Łańcuch odnosi się do pewnej liczby lat/miesięcy w przyszłości, chcę zrobić to na dziesiętne lata.
Format Generic: „aYbM”
Jeżeli jest to liczba lat, b jest liczba miesięcy te można ints i oba są opcjonalne (wraz z ich identyfikatorem)
przypadków testowych:
5Y3M == 5.25
5Y == 5.0
6M == 0.5
10Y11M = 10.91666..
3Y14M = raise ValueError("string '%s' cannot be parsed" %input_string)
Moje próby do tej pory zaangażowany dzielenie ciąg i było dość uciążliwe choć produkują poprawne wyniki:
def parse_aYbM(maturity_code):
maturity = 0
if "Y" in maturity_code:
maturity += float(maturity_code.split("Y")[0])
if "M" in maturity_code:
maturity += float(maturity_code.split("Y")[1].split("M")[0])/12
return maturity
elif "M" in maturity_code:
return float(maturity_code[:-1])/12
else:
return 0
Ściśle rzecz biorąc, "non-match" jest rzeczywiście pasujący łańcuch pusty, ponieważ obie części są opcjonalne. Zwraca 'groups()' as '(None, None)'. To twój kod podnosi wartość ValueError, a nie moduł re. Dobre rozwiązanie. – PaulMcG
Możesz ochronić przed kilkoma miesiącami> = 12 (jak wskazano w oryginalnym pytaniu) za pomocą 'r" (?: (\ D +) Y)? (? :(0? \ D | 1 [01]) M) ? \ b "' - OP nie było jasne, czy wiodące zera mogą być obecne, czy nie. I kończący się "\ b" chroni przed dopasowaniem roku z nieważnym miesiącem. – PaulMcG
Dzięki za szczegółową odpowiedź, wyłapanie tego, co faktycznie robi wyrażenie regex! Znalazłem dokumentację dotyczącą regex, która zakłada pewien poziom wiedzy i jest prawie niemożliwe do odczytania, jeśli go nie ma, więc jest to bardzo pomocne. – David258