zoukankan      html  css  js  c++  java
  • perl 正则s///与tr///

    假若我們要將比對到的字串,前後加上單引號,這裡一個特殊變數 $& 就是比對到的字串
    $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

  • 相关阅读:
    C# winform判断窗体是否已打开
    对象与json字符串转换类设计
    Redis 操作帮助类
    C# redis客户端帮助类
    RedisHelper Redis帮助类
    Vue.js实现tab切换效果
    Uni-app 使用总结
    C#中的委托和事件(续)
    12小时超级马拉松赛记
    2016年8月份
  • 原文地址:https://www.cnblogs.com/blueicely/p/2816371.html
Copyright © 2011-2022 走看看