El problema es encontrar los códigos que comienzan por 12. En negrita
se han resaltado las soluciones. Son soluciones sólo aquellas que, comienzan
por 12
en una posición múltiplo de seis.
Una solución es:
@nums = grep {m/^12/} m/\d{6}/g;
que genera una lista con los números y luego selecciona los que comienzan por
12
.
Otra solución es:
@nums = grep { defined } m/(12\d{4})|\d{6}/g;
que aprovecha que la expresión regular devolverá una lista vacía cuando
el número no empieza por 12
.
Obsérvese que se esta utilizando también que el operador |
no es greedy.
¿Se puede resolver el problema usando sólamente una expresión regular? Obsérvese que esta solución ``casi funciona'':
@nums = m/(?:\d{6})*?(12\d{4})/g;
recoge la secuencia mas corta de grupos de seis dígitos que no casan, seguida de una secuencia que casa. El problema que tiene esta solución es al final, cuando se han casado todas las soluciones, entonces la búsqueda exhaustiva hará que nos muestre soluciones que no comienzan en posiciones múltiplo de seis. Encontrará así números como el último resaltado:
@nums = m/(?:\d{6})*?(12\d{4})(?:(?!12)\d{6})*/g;
Se asume que existe al menos un éxito en la entrada inicial. Que es un extraordinario ejemplo de como el uso de paréntesis de agrupamiento simplifica y mejora la legibilidad de la solución. Es fantástico también el uso del operador de predicción negativo.
Casiano Rodríguez León