Vielleicht Perl Negative Lookbehind mit Bypass für variable Länge?

Vielleicht Perl Negative Lookbehind mit Bypass für variable Länge?

Ich habe diesen einfachen Code

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")'

und ich möchte, dass es alle Parameter=10 ersetzt, aber nicht, wenn irgendwo in der Zeile ein Hash vorangestellt ist. zB

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

Ich weiß, dass, wenn ich eine

((?<!#\s*))

Ich erhalte eine Fehlermeldung

Lookbehind mit variabler Länge ist in regulären Ausdrücken nicht implementiert

Gibt es eine Möglichkeit, die Aufgabe auf andere Weise zu erledigen?

Danke

Antwort1

Sie können beispielsweise Folgendes tun:

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

Die Idee ist, dass das #.*(das wir durch sich selbst ersetzen) alle Kommentare wegfrisst. Und im zweiten Teil der Abwechslung suchen wir in dem, parameter=...was übrig bleibt, nach Ihrem Muster (hier vorausgesetzt, dass ihm kein Nicht-Leerzeichen vorangestellt ist).

Ein anderer Ansatz ist die Verwendung von:

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

\Klegt den Anfang des zu ersetzenden Teils fest. Das mFlag führt ^eine Übereinstimmung am Anfang jeder Zeile innerhalb des Betreffs aus.

Wenn diese parameter=nur am Anfang der Zeilen zu finden sind (gefolgt von optionalen Leerzeichen), dann heißt es lediglich:

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

Antwort2

Die einzige Alternative, die mir einfällt, ist diese:

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" 

Ausgabe:

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

Wir müssen '^(?!#+$)(\s*)'zeilenweise einen negativen Lookahead verwenden. Und es akzeptiert variable Längen (vielleicht weil es sich nicht um eine mehrzeilige Zeichenfolge handelt? Das weiß ich noch nicht.)

Ich bin auf diese Idee gestoßenhttps://www.regextester.com/95226und habe es endlich in Gang gebracht.

Ich habe heute etwas Neues gelernt. Ich hoffe, Sie finden es nützlich!

PS. wir könnten auch ein einfaches verwenden, ([^#]*)wie vorgeschlagen vonterdon https://unix.stackexchange.com/a/521512/354415der im Grunde dasselbe Konzept wie hier vorgeschlagen hat, aber in einem Perl-Einzeiler implementiert hat! Sehr schön!

verwandte Informationen