¿Quizás Perl Negative Lookbehind con derivación de longitud variable?

¿Quizás Perl Negative Lookbehind con derivación de longitud variable?

tengo este código simple

perl -we 'my $file= "
    #    parameter=10
#    parameter=10
# parameter=10
    parameter=10
parameter=10
"; $file=~ s/((?<!# ))\s*parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'

y quiero que reemplace todos los parámetros = 10, pero no si está precedido por un hash en cualquier parte de esa línea. p.ej

        #    parameter=10
#    parameter=10
# parameter=10
        parameter=replaced
parameter=replaced

Sé que si proporciono un

((?<!#\s*))

me sale un error

Búsqueda hacia atrás de longitud variable no implementada en expresiones regulares

Entonces, ¿hay alguna manera de realizar la tarea por algún otro medio?

Gracias

Respuesta1

Puedes hacer algo como:

s/#.*|((?<!\S)parameter\h*=.*)/$1 ? "parameter=replaced" : $&/ge;

La idea es que #.*(que reemplazamos por sí mismo) elimine todos los comentarios. Y en la segunda parte de la alternancia, buscamos su patrón (aquí parameter=...siempre que no esté precedido por un espacio que no sea en blanco) en lo que queda.

Otro enfoque es utilizar:

s/^[^#\n]*\K(?!<\S)parameter\h*=.*/parameter=replaced/gm;

\Kestablece el inicio de la pieza a reemplazar. La mbandera coincide ^al comienzo de cada línea dentro del asunto.

Si parameter=solo se encuentran al comienzo de las líneas (seguidos de espacios en blanco opcionales), entonces eso es solo:

s/^\h*\Kparameter\h*=.*/parameter=replaced/gm;

Respuesta2

Bueno, la única alternativa que se me ocurre es esta:

FILESECTION="\
        #    parameter=10
#    parameter=10
#  parameter=10
        parameter=10
parameter=10
"

newfile=''
while IFS= read -r line ; 
    do 

    SECTIONFIXED=$( perl -le '$file=$ARGV[0]; $file=~ s/^(?!#+$)(\s*)(parameter\s*=.*)/parameter=replaced/g; print("$file\n");' "${line}" ; ) 
    newfile=$( printf "${newfile}\n${SECTIONFIXED}\n" )  
done <<< "$FILESECTION"

echo "$newfile" 

Producción:

        #    parameter=10
#    parameter=10
#  parameter=10
parameter=replaced
parameter=replaced

Tenemos que utilizar '^(?!#+$)(\s*)'una búsqueda anticipada negativa línea por línea. Y acepta longitudes variables (¿tal vez porque no está en una cadena de varias líneas? Aún no lo sé).

me encontré con esta ideahttps://www.regextester.com/95226y finalmente lo puse en marcha.

Aprendí algo nuevo hoy. ¡Espero que encuentres esto útil!

PD. También podríamos usar un simple ([^#]*)como lo sugiereterdón https://unix.stackexchange.com/a/521512/354415¡Quién sugirió básicamente el mismo concepto que aquí pero implementado en una sola línea de Perl! muy lindo !

información relacionada