簡體   English   中英

用組替換perl正則表達式

[英]perl regular expression substitution with groups

我有以下json輸入

... "somefield":"somevalue", "time":"timevalue", "anotherfield":"value" ...

在我的ksh腳本中,我希望將timevalue替換為我的值。 所以我用工作組創建了這個正則表達式

data=`cat somefile.json`
echo $data | perl -pe "s|(.*time\"\s*\:\s*\").*?(\".*)|\1%TIME%\2|g" | another-script.sh

... "somefield":"somevalue", "time":"%TIME%", "anotherfield":"value" ...

但是...我不能用數字代替,因為perl使用數字來定義組..所以這個顯然不起作用

perl -pe "s|(.*time\"\s*\:\s*\").*?(\".*)|\120:00:00\2|g"

我可以通過兩步替換來克服這個問題

perl -pe "s|(.*time\"\s*\:\s*\").*?(\".*)|\1%TIME%\2|g" | perl -pe "s|%TIME%|20:00:00|"

... "somefield":"somevalue", "time":"20:00:00", "anotherfield":"value" ...

但我敢肯定,有更好,更優雅的方法

雖然您可以使用正則表達式執行此操作,但是使用正確的工具會容易得多

jq '.time="20:00:00"' somefile.json 

如果您特別希望使用Perl,Perl的核心發行版自2011年起就包含JSON解析器,因此您可以執行以下操作:

perl -MJSON::PP=decode_json,encode_json -0 -E '$j = decode_json(<>); $j->{time} = "20:00:00"; say encode_json($j)' somefile.json

Perl不使用\\1進行替換。 如果您啟用了警告(例如,使用perl -w ),則perl會告訴您它是$1 可以通過添加{ }與周圍的數字區分開來:

perl -pe 's|(.*time"\s*:\s*").*?(".*)|${1}20:00:00$2|g'

(我還從正則表達式中刪除了所有多余的反斜杠。)

另一方面,如果只想自己替換它,那么匹配.*有什么意義呢? 不能只是

perl -pe 's|(time"\s*:\s*").*?(")|${1}20:00:00$2|g'

我不是.*.*?忠實粉絲.*? 如果您嘗試匹配帶引號的字符串的內部,則最好進行具體說明:

perl -pe 's|(time"\s*:\s*")[^"]*(")|${1}20:00:00$2|g'

我們並沒有嘗試驗證輸入字符串,因此,現在實際上也沒有理由匹配最后一個" (並用它自己替換)”:

perl -pe 's|(time"\s*:\s*")[^"]*|${1}20:00:00|g'

如果您的perl不是古老的(5.10+),則可以使用\\K來“保留”字符串的前導部分,即不要將其包括在匹配項中:

perl -pe 's|time"\s*:\s*"\K[^"]*|20:00:00|g'

現在只有[^"]*部分將被替換,從而使我們不必進行任何捕獲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM