Bash
在命令行中刪除(可能是嵌套的)文本引號
我需要在命令行中解析大量文本並用空格替換所有(可能是嵌套的)文本引號。引號用特定的語法標記:
[quote=username]quoted text[/quote]
.帶有嵌套引號的範例輸入可能類似於:
text part 1 [quote=foo] outer quote 1 [quote=bar] inner quote [/quote] outer quote 2 [/quote] text part 2 [quote=foo-bar] next quote [/quote] text part 3
預期的輸出將是:
text part 1 text part 2 text part 3
在這個問題的幫助下,我得到了它以某種方式工作(上面得到了輸出),
sed ':b; s/\[quote=[^]]*\][^[\/]*\[\/quote\]/ /g; t b'
但中間部分([^[\/]
] 是有問題的,因為引號可以包含像[
or之類的字元]
。話雖如此,如果輸入是例如,我的
sed
命令將不起作用。text part 1 [quote=foo] outer quote 1 [quote=bar] inner quote [foo] [/quote] outer quote 2 [/quote] text part 2 [quote=foo-bar] next quote [/quote] text part 3
一個問題是它
sed
似乎不支持非貪婪限定符,因此總是從輸入中擷取最長可能的匹配。這使得通常難以處理**a)使用者名和b)**引用的文本。我也猜想這
sed
不是解決這個問題的最佳工具,它甚至可能無法做這樣的事情。也許例如。perl
或者awk
可以更好地工作?現在最後一個問題是,解決這個問題的最好和最有效的方法是什麼?
如果您知道輸入不包含
<
或>
字元,您可以這樣做:sed ' # replace opening quote with < s|\[quote=[^]]*\]|<|g # and closing quotes with > s|\[/quote\]|>|g :1 # work our way from the inner quotes s|<[^<>]*>||g t1'
如果它可能包含
<
或>
字元,您可以使用以下方案對它們進行轉義:sed ' # escape < and > (and the escaping character _ itself) s/_/_u/g; s/</_l/g; s/>/_r/g <code-above> # undo escaping after the work has been done s/_r/>/g; s/_l/</g; s/_u/_/g'
使用
perl
遞歸正則表達式:perl -pe 's@(\[quote=[^\]]*\](?:(?1)|.)*?\[/quote\])@@g'
甚至,正如您提到的:
perl -pe 's@(\[quote=.*?\](?:(?1)|.)*?\[/quote\])@@g'
使用,您可以通過添加選項
perl
來處理多行輸入。-0777
使用sed
,您需要在程式碼前面加上::0 $!{ N;b0 }
以便將整個輸入載入到模式空間中。