Parte 7
7.1. Caso 1: Validar números romanos
Caracteres:
| I = 1 V = 5 X = 10 L = 50 |
|
C = 100 D = 500 M = 1000 |
Reglas generales:
- Los caracteres son aditivos, ej: I es 1, II es 2, VI es 6
- Si llamamos a { I, X, C, M } los caractares 'diez' y { V, L, D} los caracteres 'cinco'. Los caracteres diez, pueden repeterise hasta tres veces. A la cuarta vez, se resta del siguiente caracter cinco mas alto. Ejemplo: en vez de representar 4 como IIII se debe usar IV, 40 es XL, 44 es XLIV
- De forma similar ocurre con 9, IX, 90 XC, 900 CM, etc
- Los caracteres 5 no pueden repetirse, por ejemplo 10 es X, no VV
- Los numeros se leen de izquierda a derecha y el orden es muy importante. CD es 400 DC es 600. CI es 101 y IC no existe porque 99 es XCIX.
Validando miles
>>> import re
>>> pattern = '^M?M?M?$'
>>> re.search(pattern, 'M')
<_sre.SRE_Match object at 0xb7dce410>
>>> re.search(pattern, 'MM')
<_sre.SRE_Match object at 0xb7ddf870>
>>> re.search(pattern, 'MMM')
<_sre.SRE_Match object at 0xb7dce410>
>>> re.search(pattern, 'MMMM')
>>> re.search(pattern, '')
<_sre.SRE_Match object at 0xb7ddf870>
Validando cientos
| 100 = C 200 = CC 300 = CCC 400 = CD 500 = D |
|
600 = DC 700 = DCC 800 = DCCC 900 = CM |
Los patrones son:
- CD
- CM
- D opcional con cero a tres caracteres
>>> pattern = '^M?M?M?(CM|CD|D?C?C?C?)$'
>>> re.search(pattern, 'MCM')
<_sre.SRE_Match object at 0xb7dc67e0>
>>> re.search(pattern, 'MD')
<_sre.SRE_Match object at 0xb7dc6820>
>>> re.search(pattern, 'MMMCCC')
<_sre.SRE_Match object at 0xb7dc67e0>
>>> re.search(pattern, 'MCMC')
>>> re.search(pattern, '')
<_sre.SRE_Match object at 0xb7dc6820>
Validando decenas y unidades
>>> pattern = '^M?M?M?(CM|CD|D?C?C?C?)(XC|XL|L?X?X?X?)(IX|IV|V?I?I?I?)$'
>>> re.search(pattern, 'MMVIII')
<_sre.SRE_Match object at 0xb7ddaa70>
>>> re.search(pattern, 'MCMLXXVIII')
<_sre.SRE_Match object at 0xb7de6200>
>>> re.search(pattern, 'MCMLXXXX')
>>>
Sintaxis {n,m}
pattern = '^M{0,3}$'
>>> re.search(pattern, 'M')
<_sre.SRE_Match object at 0xb7dce410>
>>> re.search(pattern, 'MM')
<_sre.SRE_Match object at 0xb7ddf870>
>>> re.search(pattern, 'MMM')
<_sre.SRE_Match object at 0xb7dce410>
>>> re.search(pattern, 'MMMM')
>>> re.search(pattern, '')
<_sre.SRE_Match object at 0xb7ddf870>
>>> pattern = '^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
>>> re.search(pattern, 'MMVIII')
<_sre.SRE_Match object at 0xb7de61b0>
>>> re.search(pattern, 'MCMLXXVIII')
<_sre.SRE_Match object at 0xb7de6200>
>>> re.search(pattern, 'MCMLXXXX')
Expresiones regulares verborrágicas
- Los espacios en blanco son ignorados
- Los comentarios son ignorados
>>> pattern = """
^ # beginning of string
M{0,4} # thousands - 0 to 4 M's
(CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
# or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
# or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
# or 5-8 (V, followed by 0 to 3 I's)
$ # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE) 1
<_sre.SRE_Match object at 0x008EEB48>
>>> re.search(pattern, 'MCMLXXXIX', re.VERBOSE) 2
<_sre.SRE_Match object at 0x008EEB48>
>>> re.search(pattern, 'MMMMDCCCLXXXVIII', re.VERBOSE) 3
<_sre.SRE_Match object at 0x008EEB48>
>>> re.search(pattern, 'M')
7.2 Caso 2: pareseando números telefónicos
Casos:
- 0351-433-3055
- 03514333055
- 0351-4333055
- 0351.433.3055
>>> phonePattern = '^(\d{4}).?(\d{3}).?(\d{4})$'
>>> re.compile(phonePattern)
<_sre.SRE_Pattern object at 0x8253e38>
>>> phone = re.compile(phonePattern)
>>> phone.search('0341.433-3055').groups()
('0341', '433', '3055')
>>> phone.search('0341.4333055').groups()
('0341', '433', '3055')
>>> phone.search('03414333055').groups()
('0341', '433', '3055')
Mas lectura
- Regular Expression HOWTO explica las expresiones regulares en Python.
- Python Library Reference resume el módulo re.
- El libro Mastering Regular Expressions de Jeffrey E F Friedl cubre en profundidad las expresiones regulares para niveles iniciales como avanzados.
- Dive into python continua el ejemplo del parser de números telefónicos.