Cómo encontrar los índices de patrones de sub-listas en Perl.
Tengo una lista más larga cuyos elementos son símbolos de varios caracteres, por ejemplo:
@c = qw(iim v7 v7 iM iv7 iM <strong>im iv7 iv7 bviiM</strong> im biio iim bviim biiM biim bviM bviM ivm iih v7 v7 v7 iiim iiih vi7 iim v7 v7 iM iv7 iM <strong>im iv7 bviiM</strong> im biio iim bviim bviim iiio iim v7 v7 v7 vm i7 ivM iiih vi7);
Me gustaría encontrar los índices en esta lista que coincidan con sub-listas del tipo S1+ S2+ S3+, donde el “+” significa que coincida una o más veces. Entonces, por ejemplo, el patrón de sub-lista (im iv7 bviiM)
coincidiría tanto con (im iv7 iv7 bviiM)
como con (im iv7 bviiM)
como se muestra en negrita anteriormente. El código proporcionaría los índices 6, 7, 8, 9 para la primera coincidencia y 32, 33, 34 para la segunda.
A simple vista, esto no parece ser difícil, y he intentado implementarlo con una variedad de métodos, incluyendo expresiones regulares, pero hasta ahora me ha vencido. Si hay una forma sencilla de hacer esto, estaría agradecido por cualquier ayuda.
davy.ai
Para resolver este problema, una posible manera es iterar a través de la lista y usar una expresión regular para verificar si el elemento actual coincide con el patrón S1+ S2+ S3+. Podemos usar el operador de coincidencia no codicioso
?
para asegurarnos de encontrar la coincidencia más corta posible. Una vez que encontramos una coincidencia, registramos los índices y continuamos la búsqueda desde el siguiente elemento.Aquí está una implementación utilizando Perl:
Explicación:
qr//
, que nos permite almacenar una expresión regular en una variable para su uso posterior. El patrón(im iv7 bviiM)+?
coincide con los tres símbolos en secuencia, una o más veces, de manera no codiciosa.@indices
para almacenar los índices coincidentes y comenzamos a iterar a través de la lista con una variable de índice$i
.$c[$i]
coincide con el patrón con la expresión regular/$pattern/
. Si coincide, lo agregamos a la sublista actual e incrementamos el índice para continuar la búsqueda desde el siguiente elemento. Si no coincide, pasamos al siguiente elemento.split / /, $sublist
, contamos el número de elementos conscalar
y restamos eso al índice actual$i
para obtener el rango de índices que coincidieron con la sublista. Insertamos este rango en@indices
.@indices
.