• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

perl 正则s///与tr///

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
假若我們要將比對到的字串,前後加上單引號,這裡一個特殊變數 $& 就是比對到的字串
$str = "What a wonderful wonderful world."; $str =~ s/w/'$&'/g; # $str = "What a 'w'onderful 'w'onderful 'w'orld."

假設我想把找到的結果全轉成大寫,一般的置換就傷透腦筋了,可是perl提供了不錯的解法,但是要使用函數,就得加上 e 修飾子:

$str = "What a wonderful wonderful world."; $str =~ s/w\w+/uc($&)/ge; # $str = "What a WONDERFUL WONDERFUL WORLD"

如果沒加 e 修飾子,則函式會被當成字串丟出來: What a uc(wonderful) uc(wonderful) uc(world)

再來比較麻煩的是字串中的換行 \n,字串中的換行字元 '\n' 被當成是一個字元來處理,所以假設一個具有換行字元的(多行的的字串,希望比對時忽略那個換行字元,就要加上 s 修飾子:

$str = "What a wonder\nful wonderful world."; $str =~ s/wonder.?ful/www/g; print $str;

What a wonder ful

www world
接下來加上 s 修飾子後,\n就等於是"一個字元",也等於'\n';否則未加s的情況則不屬於一個字元,也就是和 '.' 比對不會成功: $str =~ s/wonder.?ful/www/sg;

What a www www world
如果我們堅持一定要和換行比對成功,則:注意沒加 s $str =~ s/wonder\nful/www/g;
What a www wonderful world
 
另外比較少見的情形下會用到的 m 修飾子:一般比對時假設要找出字串結尾的字串,常會用變換字元 $,在帶有換行的字串中,變換字元 $只會比對最後的換行或是字串結尾。如果希望 $能取得符合帶有換行的字串中,每個換行都視為結尾的話,就要加 m。這樣形容比較抽象,看個範例:
$str = "line123\nline456\nline789";
$str =~ s/\d+$//g; <== 注意沒有加 m print $str;
line123
line456
line    <==只比對最後一個
$str =~ s/\d+$//mg; <== 注意現在加了 m print $str;
line <==每個換行符號都視為結尾
line
line
 
寫了這麼多 s///,現在來說 tr///,tr 的語法和 s 好像一樣,其實還差異滿大的,tr 主要作為項目清單的置換: tr/原來比對清單/目的比對清單/選項 perl 的 tr把置換的功能再擴張,雖然 s很強,可是也有做不到的事,例如今天要把大寫換成小寫,「同時」小寫也換成大寫,s就一籌莫展了,但 tr 可以搞定:
$str = "Aine123\nBine789"; $str =~ tr/a-zA-Z/A-Za-z/; print $str;

aINE123 bINE789

同時tr 也可以用來計算字數,只需要把自己換成自己就好,例如以下範例計算$doc出現的數字個數
$doc="<78>Nov 3 11:20:01 163.17.44.1 crond[30367]: (root) CMD (LANG=C LC_ALL=C /usr/bin/mrtg /etc/mrtg/mrtg.cfg --lock-file /var/lock/mrtg/mrtg_l --confcache-file /var/lib/mrtg/mrtg.ok)";
print $doc=~ tr/0-9/0-9/;

結果:22

這裡要注意,上式的 $doc 本身並沒有改變,所以如果下一行 print $doc; 得到的結果還會是原字串。所以如果要取得計算的字數,就得寫成這樣:
$count = $doc=~ tr/0-9/0-9/;
 tr 還有一個別名,叫作 y/// 所以要把數字0和9互換,可以寫成
$doc =~ y/09/90/; 或是寫成(把 / 換成 |; $doc =~ y|09|90|;
接來看看 tr 的選項,tr 只有三個選項,英文是 perldoc 的說明,我把他的意思用我的話寫出來:
c Complement the SEARCHLIST. <== 清單沒寫到的就補給他右邊清單的最後一個字元
d Delete found but unreplaced characters. <== 對照表中沒有的項目就刪掉
s Squash duplicate replaced characters. <== 連續重覆出現的字壓成一個
來看看範例:
my $text = 'good cheese'; $text =~ tr/eo/eu/s; print "$text\n"; 

# 結果 gud chese ,

連續重覆出現的字已被壓成一個
my $big = 'vowels are useful'; $big =~ tr/aeiou/AEI/d; 

# 注意看對照表左邊只有三個字母,所以如果遇到 ou,就會被刪掉 print "$big\n";

# 結果 vwEls ArE sEfl 合併以上兩個參數

my $text = 'good cheese'; $text =~ tr/eogd/eu/ds; 

# 寫成 ds 或sd 都可以,順序不重要 print "$text\n";

# 結果 u chese
最後來看 c 這個選項,c 較複雜不易懂,大致以我的大腦所知的說明如下: tr/左清單/右清單/c 規則、左清單沒有的,就補右清單的東西

my $text = 'good cheese'; $text =~ tr/eo/_/c;

#注意看對照表右邊只有二個字母,只要右邊清單沒列到的就補'_',包括空白 print "$text\n";

# 結果 _oo____ee_e

如果右清單寫了不只一個呢?會怎樣?其實補的時候還是只會拿右清單的最後一個

$doc="<78>Nov 3 11:20:01 163.17.44.1 crond[30367]"; $doc =~ y/a-zA-Z/a-z/c; 

# 結果不是英文全都補了右清單的最後一個字元'z'

$doc= zzzzzNovzzzzzzzzzzzzzzzzzzzzzzzzzcrondzzzzzzz


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
perl模块安装发布时间:2022-07-22
下一篇:
Perl IO:简介和常用IO模块发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap