设为首页 收藏本站
查看: 738|回复: 0

[经验分享] perl 正则s///与tr///

[复制链接]

尚未签到

发表于 2015-12-26 07:00:58 | 显示全部楼层 |阅读模式
假若我們要將比對到的字串,前後加上單引號,這裡一個特殊變數 $& 就是比對到的字串




$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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-156357-1-1.html 上篇帖子: Perl语言入门-第七章-漫游正则表达式王国-习题 下篇帖子: 使用Perl的File::Path模块删除非空文件夹
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表