Puede usar la siguiente expresión regular para esto:
^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
Desglosándolo, M{0,4}
especifica la sección de miles y básicamente lo restringe entre 0
y 4000
. Es un relativamente simple:
0: <empty> matched by M{0}
1000: M matched by M{1}
2000: MM matched by M{2}
3000: MMM matched by M{3}
4000: MMMM matched by M{4}
Por supuesto, podría usar algo como M*
permitir cualquier número (incluido cero) de miles, si desea permitir números más grandes.
El siguiente es (CM|CD|D?C{0,3})
, un poco más complejo, esto es para la sección de cientos y cubre todas las posibilidades:
0: <empty> matched by D?C{0} (with D not there)
100: C matched by D?C{1} (with D not there)
200: CC matched by D?C{2} (with D not there)
300: CCC matched by D?C{3} (with D not there)
400: CD matched by CD
500: D matched by D?C{0} (with D there)
600: DC matched by D?C{1} (with D there)
700: DCC matched by D?C{2} (with D there)
800: DCCC matched by D?C{3} (with D there)
900: CM matched by CM
En tercer lugar, (XC|XL|L?X{0,3})
sigue las mismas reglas que la sección anterior pero para el lugar de las decenas:
0: <empty> matched by L?X{0} (with L not there)
10: X matched by L?X{1} (with L not there)
20: XX matched by L?X{2} (with L not there)
30: XXX matched by L?X{3} (with L not there)
40: XL matched by XL
50: L matched by L?X{0} (with L there)
60: LX matched by L?X{1} (with L there)
70: LXX matched by L?X{2} (with L there)
80: LXXX matched by L?X{3} (with L there)
90: XC matched by XC
Y, por último, (IX|IV|V?I{0,3})
es la sección de unidades, la manipulación 0
a través 9
y también similar a las dos secciones anteriores (números romanos, a pesar de su aparente rareza, siguen algunas reglas lógicas vez que averiguar lo que son):
0: <empty> matched by V?I{0} (with V not there)
1: I matched by V?I{1} (with V not there)
2: II matched by V?I{2} (with V not there)
3: III matched by V?I{3} (with V not there)
4: IV matched by IV
5: V matched by V?I{0} (with V there)
6: VI matched by V?I{1} (with V there)
7: VII matched by V?I{2} (with V there)
8: VIII matched by V?I{3} (with V there)
9: IX matched by IX
Solo tenga en cuenta que esa expresión regular también coincidirá con una cadena vacía. Si no quiere esto (y su motor regex es lo suficientemente moderno), puede usar una mirada positiva hacia atrás y hacia adelante:
(?<=^)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})(?=$)
(la otra alternativa es simplemente verificar que la longitud no sea cero de antemano).