perl 點點滴滴 當然代替awk和sed

perl語言的優勢在於語法靈活,正則表達式強大。它的缺點其實也在於語法過於靈活,正則強大而複雜。但是用來文本處理工具還是很不錯的工具。

最近翻了一下《精通正則表達式》,看到幾個強大而實用的正則表達式用法:

1. 利用 正則中的 環視 操作符來爲數字添加分割逗號,例如:35,738,480

$num = 35738480;

$num =~ s!(?<=/d)(?=(/d/d/d)+$)!,!g

#這個式子主要可以用在統計郵件中

2. 利用perl的動態正則表達式進行 嵌套tag的匹配

問題: 匹配 標紅部分:

<div>

<div><table><div>AA</div></table></div> <div>BB</div>

<div>CC</div>

<div><table>DD</table></div> 

</div>

之前自己想到的一種解法:普通正則表達式 匹配兩層tag嵌套:

$str='<div>

<div><table><div>AA</div></table></div> <div>BB</div>

<div>CC</div>

<div><table>DD</table></div> 

</div>

';

$str =~ m!<div>(.*?(?:<div>.*?(?:<div>.*?</div>.*?)*</div>.*?)*)</div>!xs;

print "$1/n";

其中(?:)表示不用於捕獲的分組,末尾的x表示寬鬆排列允許正則中包含空格和註釋,末尾的s表示點號通配符匹配換行。m!!perl語言的正則匹配語法。

但是這種方法只能匹配最多兩層的<div></div>的標籤嵌套。

實際上使用perl特有的功能,動態正則表達式可以實現匹配多層的標籤嵌套(當然用自己用棧或者別的方式也可以實現,這裏只涉及正則)。

#首先先聲明一個嵌套結構

my $levelN;

$levelN = qr!.*?<div>(?:.*?|(??{$levelN}))</div>.*?!xs;

#應用這個嵌套結構

$str =~ m!<div>(.*?(?:$levelN)*)</div>!xs

print "$1/n";

3. 利用perl的命令行接口代替grepsed

問題:從頁面中提取符合模式的 url 並轉換爲有效形式

頁面中的url形式:<a href="/f421"> 

轉換爲:輸出 http://bbs.kaoyan.com/f421p1

實現這個功能實際只需要一行代碼

perl -n -e 'm/"//(f/d+)"/;print "http://bbs.kaoyan.com/$1p1/n"' index.html|sort -u

這個腳本實現從index.html頁面中獲取論壇的頻道url的功能。

其中-n 表示對文件中每一行進行處理 -e後面接上perl腳本,最後重定向到sort進行排重。個人覺得這個比grep+sed要直觀好用,並且可以利用到perl語言強大的正則功能。

 

Perl命令行參數:
-0< 數字>      (用8進製表示)指定記錄分隔符($/變量),默認爲換行
-00              段落模式,即以連續換行爲分隔符
-0777           禁用分隔符,即將整個文件作爲一個記錄
-a                 自動分隔模式,用空格分隔$_並保存到@F中。相當於 @F = split ”。分隔符可以使用-F參數指定
-F                 指定-a的分隔符,可以使用正則表達式
-e                執行指定的腳本。
-i< 擴展名>    原地替換文件,並將舊文件用指定的擴展名備份。不指定擴展名則不備份。
-l                  對輸入內容自動chomp,對輸出內容自動添加換行
-n                 自動循環,相當於 while(<>) { 腳本; }
-p                 自動循環+自動輸出,相當於 while(<>) { 腳本; print; }

發佈了40 篇原創文章 · 獲贊 6 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章