來源:早起Python作者:大奎大家好,我是早起。在之前的辦公自動化系列文章,我們大多基於 Python 實現,因為使用 Python 具有靈活、強大的特點。使用 VIM 具有快速、視覺化的優勢。
2021-06-30 11:28:11
來源:早起Python
作者:大奎
大家好,我是早起。
在之前的辦公自動化系列文章,我們大多基於 Python 實現,因為使用 Python 具有靈活、強大的特點。使用 VIM 具有快速、視覺化的優勢。兩者對大量同構文字進行修改,可大幅提高工作效率。但相較於編寫 Python 程式,VIM 視覺化執行更勝一籌。
這也提示我們,Python 不是萬能的——至少在某些方面、某些場景下,不一定是最優解。合適的工具運用到合適的場合是效率最高的方式。不能自己是錘子,看什麼就都是釘子。
在對 VIM 不熟悉的使用者看來,VIM 的操作過程可能更復雜、難懂。但這是先入為主的印象,VIM 處理文字還是很方便快捷的:我們有了 Python 這把錘子,不排斥再來 VIM 這個鋸嘛,這樣才能「工欲善其事,必先利其器」。本文將對比使用 Python 和 VIM 對同一個文字編輯任務處理的情況。
01、需求說明
有大量類似結構的文字檔案需要處理,目錄結構如下:
E:.└─content ├─a │ └──content.txt ├─b │ └──content.txt └─c └──content.txt
其中的每個檔案 content .txt內容結構如下:
<vsbimgsrc="/_vsl/012A716D176AFA6EBBAF64BD4CB63BCA/994A4168/AE5BB"></vsbimg><vsbimgsrc="/_vsl/2ADBFFCE33AAE9B2E79E758EF6AD5626/CEFD12BB/A8DC5"></vsbimg>
要求是:
將 <vsbimg></vsbimg> 標籤改為 <img></img> 標籤。將 /_vsl/012A7 表示的相對地址,變成另一個 URL 地址,如 http://image.xx.com/image/。將 src 的最後兩個/改為 _。將整個 src 最後加上圖片字尾 .png。修改後的檔案為:
<imgsrc="http://image.xx.com/image/16D176AFA6EBBAF64BD4CB63BCA_994A4168_AE5BB.png"></img><imgsrc="http://image.xx.com/image/FCE33AAE9B2E79E758EF6AD5626_CEFD12BB_A8DC5.png"></img>
02、Python實現
首先讓我們用 Python 編寫程式來完成,程式碼比較簡單,但面對如此簡單的問題,寫一個程式還是「高射炮打蚊子」 了。而且偵錯 Python 正則表示式,並不是一個直觀的過程。
import osimport redefrep(strs): strs = re.sub(r'<vsbimg',r'<img',strs) strs = re.sub(r'</vsbimg',r'</img',strs) strs = re.sub(r'(/_vsl/.*?)/',r'1_',strs) strs = re.sub(r'(/_vsl/.*?)/',r'1_',strs) strs = re.sub(r'(src=".*?)"',r'1.png"',strs) strs = re.sub(r'src="/_vsl/.{5}',r'src="http://image.x.com/image/',strs) return strsdefop(fn): fn2 = os.path.join(os.path.split(fn)[0],os.path.split(fn)[1]+'new') with open(fn,encoding='utf-8') as f,open(fn2,'w',encoding='utf-8') as f2: for l in f.readlines(): l = rep(l) f2.write(l)for r,_,fs in os.walk('content'): for f in fs: if f.endswith('txt'): fn = os.path.join(r,f) op(fn)
殺雞不用牛刀,咱們改用 VIM 試試。
VIM 最主要好處就是:構造查詢正則表示式時結果視覺化,這樣就可以逐步求精地寫正則表示式,反之剛才寫程式時,我得來回測試,十分費力。
03、VIM實現
下面是使用 VIM 實現需求所需要注意的幾點
本例使用 VIM 中的 :%s 替換指令很容易完成替換操作。正則表示式構造需要慢慢來。如果牽涉到複雜替換時,還需要對搜尋結果分組,以便使用分組結果。為了批量完成序列替換操作,需要將操作寫入批處理指令碼,再用 :source 執行指令碼。以上操作在單檔案中執行,為了在許多檔案中同時完成,需要使用緩衝區執行 :bufdo 命令。3.1 構造正則表示式搜尋
為了替換 <vsbimg,我們構造一個查詢正則表示式。
構造出的表示式如下:
/<vsbimg
這個表示式搜尋了 <vsbimg 開頭的所有內容。
「在 / 指令後按向上箭頭表示上一次輸入的查詢歷史。按 q/ 表示所有查詢歷史,可以在此歷史上修改,這樣就可以逐步精化。」
3.2 替換
常規替換指令 :%s/pattern/string/g,留空的查詢域表示上次搜尋的結果。在上步查詢基礎上,我們可以使用 :%s//<img/g 的方式完成更改。
「這個操作很重要:很多複雜的正則表示式,不可能一步直接構造出來;採用搜尋的方法,可以高亮顯示每次的搜尋結果,進而改進正則表示式。而替換時留空查詢域,直接表示上次搜尋結果,極大方便了替換操作。使一步替換操作轉換為:搜尋,替換兩步,降低了難度,提高了效率。」
注意以下替換語句,使用了 轉義字元來匹配 </vsbimg> 的特殊字元 。
:%s/</vsbimg/</img/g
3.3 搜尋結果分組、使用
在對 轉換為 _ 的操作中,我們需要記住之前的匹配物件,用來在替換時作為不改變的內容引用。
這裡用 () 圈起來需要分組的部分,在搜尋或者替換部分用 1 表示第一個分組,以此類推。具體看程式碼:
:%s/("/_vsl/.{-1,})//1_/g
因為有兩個 ,所以需要執行兩次。
替換域裡的 1 指代的是 () 中的匹配內容,也就是 src 從 _vsb/ 之後遇到的第一個 為止的內容。當替換時,我們依然把這部分,用 1 使用上,只是把 改為_。
3.4 非貪婪模式
上例子可見 .{-1,} 的程式碼,這是對任意字元進行非貪婪匹配,以縮小 / 適配範圍,適配到第一個 / 為止,不再繼續貪婪最大適配。
在給 src 新增 .png 字尾時,也使用了分組和非貪婪概念。將 src 到第一個"的內容視為一個分組,然後替換為分組內容和 .png"。
:%s/(src=".{-1,})"/1.png"/g
將相對地址修改為 URL 時,URL 部分需要進行很多次轉義。
:%s/src="/_vsl/.{5}/src="http://192.168.22.117/cnv/jflyfox/mtg/cnvImage//g
最後,我們把以上修改儲存進原檔案:w。
以上,我們通過搜尋和替換操作,完成了對單個檔案的修改。
如果對每一個檔案都執行如上的程式,就顯得比較複雜了,好在 VIM 支援批處理操作。
3.5 批處理檔案執行 source
這裡,我們將以上操作步驟,寫到 oper.vim 檔案中去。
:%s/<vsbimg/<img/ge:%s/</vsbimg/</img/ge:%s/("/_vsl/.{-1,})//1_/ge:%s/("/_vsl/.{-1,})//1_/ge:%s/(src=".{-1,})"/1.png"/ge:%s/src="/_vsl/.{5}/src="http://192.168.22.117/cnv/jflyfox/mtg/cnvImage//ge:w
在另一個新的待處理檔案中,我們輸入 :source oper.vim,就將以上所有操作在新檔案中重做。
操作一個新檔案可行了,如何操作大批量的檔案呢?
「按 q: 表示所有替換歷史,將這些替換命令拷貝出來,避免輸入帶來的麻煩和錯誤。」
3.6 緩衝區批量執行 bufdo
VIM 的 Buffer 緩衝區,相當於記憶體。當我們具體修改某個檔案時,實際是在記憶體中對他進行修改,只有當輸入 :w 命令時,修改才寫回硬碟。
使用 vim a.txt b.txt 指令,一次性開啟兩個檔案,當前訪問和修改的是 a.txt。使用指令 :bnext 在緩衝區之間跳轉。指令 :ls 列出了當前所有緩衝區檔案。
使用 vim *.txt,批量開啟 txt 字尾的檔案。
在當前緩衝區列表上的所有檔案執行命令,輸入 :bufdo excommand。
本文中我們開啟目錄 a,b,c 下的 content.txt 檔案,使用 vim content/*/*.txt 即可。在開啟的視窗中執行 :ls 即可檢視當前緩衝區檔案。確認無誤後,執行 :bufdo source oper.vim ,即可完成對所有緩衝區檔案的修改。
「抑制錯誤:當我們使用以上 vim 指令碼時,很容易因為搜尋規則或者文字問題導致出錯,進而導致指令碼停止。在每個替換語句之後加上 e ,用來表示抑制錯誤,就可以修正這個問題。
04、小結
使用 VIM 中的替換指令很容易完成操作。但正則表示式構造需要慢慢來。逐步求精,還可能需要分組和非貪婪模式。批處理檔案 .vim 和 :source 命令可以大大簡化工作。緩衝區列表執行 :bufdo 命令則進一步提高工作效率。
VIM 編輯器處理這個問題,使用的技巧都比較通用,可以遷移到其他文字處理任務中。最主要的是,構造正則表示式的過程是直接反饋、視覺化的,利於構造複雜表示式。
Python 不是萬能的——至少在某些方面、某些場景下,不一定是最優解。合適的工具運用到合適的場合是效率最高的方式。不能自已是錘子,看什麼就都是釘子。
相關文章
來源:早起Python作者:大奎大家好,我是早起。在之前的辦公自動化系列文章,我們大多基於 Python 實現,因為使用 Python 具有靈活、強大的特點。使用 VIM 具有快速、視覺化的優勢。
2021-06-30 11:28:11
【6月30日訊】相信大家都知道,在2020年底,我們國內實力最輕的晶片製造巨頭—中芯國際被爆出了一則重磅訊息,那就是中芯國際的技術大神梁孟鬆提出了離職申請,要知道梁孟鬆在中芯
2021-06-30 11:27:39
「你愛我,我愛你,蜜雪冰城甜蜜蜜~」如果說,4月份的你還在問「什麼是快樂星球」,5月份的你在「心疼哥哥」,那麼6月份,歡迎來到被蜜雪冰城支配的世界相信很多人最近都在微博上看到了
2021-06-30 11:26:57
自從2008年第一款的心繫天下系列手機-三星W699釋出以來,心繫天下系列便開啟了三星高階深度定製旗艦手機的道路。每年一款的心繫天下系列手機,總會帶給我們不一樣的驚喜,每
2021-06-30 11:26:22
用手機攝影,橫拍和豎拍有什麼區別?你在進行手機攝影的時候,你喜歡用橫拍還是喜歡使用豎拍?我覺得這應該是困擾很多使用者的內容。有的人特別喜歡拍照的時候用豎拍,因為豎拍它能夠
2021-06-30 11:07:08
學好英語是件讓許多學生感到困難的事情,無論背過多少單詞,平日裡做作業總能見到生詞,這時,很多的學生會拿起手機查單詞,結果把持不住玩起手機,不知不覺又浪費了半小時。至於生詞怎
2021-06-30 11:06:28