2012-11-13 85 views
1

使用Perl find我無法成功地在搜索字符串中轉義DOCTYPE聲明。這裏是我正在搜索的一個字符串的例子;在Perl搜索中正確轉義doctype聲明字符串

find . -type f|xargs -d "\n" perl -pi -e 's/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1\.0 Transitional//EN" "http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-transitional\.dtd">//g' 

用什麼都替換doctype聲明。請如果有人可以正確地轉義此字符串,以便perl查找可以找到任何字符串將不勝感激。

+2

爲什麼'/ g'有關係嗎?我沒有跨越許多HTML文檔有多個文檔類型。 – simbabque

+0

我認爲g是全局的,所以如果找到的話它會替換一個文件中的多個實例。 – user1822148

+0

這是我的觀點。文檔類型位於HTML文檔的頂部,只有一次。爲什麼試圖多次替換它,如果只有一個它的實例? – simbabque

回答

2

您可以在Perl中使用/以外的其他分隔符。試試這個:

s{<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1\.0 Transitional//EN" "http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-transitional\.dtd">}{}g 

由於斜線不再限定正則表達式,所以使用起來很安全。

+0

實際上,這段代碼完美工作,但當我再次嘗試搜索'{include('titles.php')} {replacement} g'時,它不會在任何文件中找到這段PHP代碼。爲什麼是這樣?我嘗試轉義括號,引號,句號,仍然沒有用? – user1822148

+0

@ user1822148可能與您的其他命令有關。我想在php中你也可以使用'''而不是'''。你試過嗎?'s/include(\ s * ['「] titles \ .php ['」] \ s *)/ replacement/g ' – simbabque

+0

我嘗試了你發佈的內容,並且在bash:語法錯誤附近出現了令人意想不到的令牌'''' – user1822148

0

如果DOCTYPE是在同一行,最好這樣寫的:

find . -type f -exec sed -i '/DOCTYPE/d' {} + 

perl

find . -type f -exec perl -i -ne 'print unless /DOCTYPE/' {} + 

避免保持一個空行。

注意

  • -i開關修改文件。用於測試目的
4

至於其他人建議,在你的正則表達式的各種'/'人物需要有'\'轉義因爲Perl會讀他們爲結束s///;過早,否則,導致一些錯誤刪除它。在處理這些問題時,你總是需要留意特殊的人物,因爲我看到你已經在各個時期完成了。

's/ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1\.0 Transitional//EN" "http://www\.w3\.org/TR/xhtml1/DTD/xhtml1-transitional\.dtd">//g' 

可以更改一個s///;您的分隔符別的東西,比如 s###s{}{}幫助allieviate的問題,我一般推薦這樣做,如果你正在使用HTML。

即便如此,我仍然會盡量簡化正則表達式,儘可能多地爲應用程序提供實用性。由於像這樣的HTML可能會非常難以處理,請嘗試使用任何類型的正則表達式的非貪婪匹配,但使用<>來捕獲特定標記。例如,您可以使用正則表達式,如本...

s{<!DOCTYPE .*?>}{}s

,有點explaind格式...

s{ 
    <!DOCTYPE # opening doctype tag 
    \s   # one whitepsace 
    .*?   # anything (even newlines because of /s flag) non-greedily 
    >   # until the first closing greater than 
}{}xs;   # x is ignore whitespace, s is have '.' match anything (even \n) 

此示例使用/x標誌置評出來,說明一切,但是如果你是在命令行上這樣做的話,這不是必須的。

我不能說你的問題的其餘部分,因爲我不熟悉shell命令,只對正則表達式部分。

0

雖然已經覆蓋了備用分隔符(例如,s###),我想補充使用\Q\E去除其他逃脫的需求:

s#\Q<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\E##g' 
+0

我也試過這樣的搜索.php文件的代碼片段,比如搜索include('file.php'),但是perl find找不到任何字符串,比如這可能是簡單的,但我不能搜索和替換使用Perl搜索這樣的PHP代碼。 – user1822148