2015-06-16 24 views
1

我有一個乳膠文件,我想擺脫\end{quoting}之前的最後一個\\如何從a到b的最後一場比賽進行搜索和替換?

我工作的文件的部分類似於這樣:

\myverse{some text \\ 
some more text \\}% 
% 
\myverse{again some text \\ 
this is my last line \\}% 
\footnote{possibly some footnotes here}% 
% 
\end{quoting} 

超過幾百行,可能覆蓋50 quoting環境。

我試過:%s/\\\\}%\(\_.\{-}\)\\end{quoting}/}%\1\\end{quoting}/gc,但不幸的是non-greedy量詞\{-}仍然過於貪婪。 它捕捉從我的示例的第二行開始,直到引用環境結束,我猜貪婪的量詞會追上文件中的最後一個\end{quoting}。有沒有可能通過搜索和替換來做到這一點,或者我應該爲此寫一個宏嗎?

編輯:我的預期產出將是這個樣子:

this is my last line }% 
\footnote{possibly some footnotes here}% 
% 
\end{quoting} 

(我要補充一點,我已經現在寫一個小宏解決的任務,我還是很好奇,如果它也可能通過搜索和替換完成)。

+1

什麼是你的預期產出? – anubhava

+0

@anubhava請參閱我的編輯。 –

回答

2

認爲你想從最後發生\\}%之前end{quoting}匹配,直到end{quoting},在這種情況下,你真的不希望任何字符\_.),你想「任何不是\\}%的字符」(是的,我知道這不是一個字符,但基本上就是這樣)。

所以,簡單地(ha!)改變你的模式使用\%(\%(\\\\}%\)\@!\_.\)\{-}而不是\_.\{-};這意味着該模式不能包含多個序列,從而實現您的目標(據我所知可以確定)。

這將使用負零寬度前瞻模式\@!,以確保爲任何字符的下一場比賽,比限制爲不符合我們要避免特定文本(但其他的,什麼都否則仍然匹配)。有關更多這些信息,請參閱:help/zero-width。

I.e.您的最終命令是:

:%s/\\\\}%\(\%(\%(\\\\}%\)\@!\_.\)\{-}\)\\end{quoting}/}%\1\\end{quoting}/g 

(我注意到你的「預期」的輸出不包含由於某種原因,第幾行,是他們只是省略或應該將其刪除命令?)

+0

我認爲這是一個很好的答案(比我的好得多),應該被接受爲工作解決方案。至少,它值得讚賞。 –

+1

@AnthonyGeoghegan你是對的。很好的答案。 –

1

你在正確的軌道上使用非貪心。 Vim的幫助文件 狀態,

「{ - }」是一樣的「*」,但使用最短匹配優先算法。

但是,下一行會警告您遇到的問題。

BUT:早開始的匹配優於較短的匹配: 「一個{ - } B」 匹配 「AAAB」 在 「xaaab」。

據我所知,你最好的解決方案是使用宏。

相關問題