Perl Negative Lookbehind 可能带有可变长度绕过?

Perl Negative Lookbehind 可能带有可变长度绕过?

我有这个简单的代码

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

我希望它替换所有parameter=10,但如果它前面有该行任何地方的散列,则不替换。例如

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

我知道如果我提供

((?<!#\s*))

我收到一个错误

正则表达式中未实现可变长度lookbehind

那么有没有办法通过其他方式来完成任务呢?

谢谢

答案1

你可以这样做:

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

这个想法是#.*(我们用它自己替换)将咀嚼掉所有评论。在交替的第二部分中,我们在剩下的内容中查找您的模式(此处parameter=...前提是其前面没有非空格)。

另一种方法是使用:

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

\K设置要替换的部分的开始位置。该m标志^在主题内每行的开头进行匹配。

如果这些parameter=只能在行的开头找到(后跟可选的空格),那么那就是:

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

答案2

好吧,我能想到的唯一选择是:

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" 

输出:

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

我们必须'^(?!#+$)(\s*)'逐行使用负前瞻。并且它接受可变长度(也许是因为它不在多行字符串上?还不知道。)

我遇到了这个想法https://www.regextester.com/95226终于开始了。

我今天学了些新东西。希望你觉得这个有用!

附言。我们还可以使用一个简单的([^#]*)建议特登 https://unix.stackexchange.com/a/521512/354415谁提出了与此处基本相同的概念,但在 Perl Oneliner 中实现!很不错 !

相关内容