
我有這個簡單的程式碼
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 中實現!很不錯 !