zoukankan      html  css  js  c++  java
  • Perl 语言入门69

    ---- 第6章 哈希-----------

    简介

    键值对。键和值都是任意标量,但键总是会被转换成字符串。
    键唯一,值可重复。
    应用场景:一组数据对应到另一组数据时。 如找出重复/唯一/交叉引用/查表等

    访问哈希元素

    $name{'fred'} = 'peng';
    $name{'barney'} = 'guo';
    foreach my $person (qw(barney fred)){
        print "you are $person $name{$person}.\n";
    }
    
    #胖箭头
    my %hash = (
        'red' => 'peng', #键的引号一般可省去
        'blue' => 'guo',
        'green' => 'bai',
    );
    
    

    访问整个哈希

    %hash = (12,"you",4,"are");
    @array = %hash;
    print "@array\n" #元素顺序会变
    

    哈希赋值

    my %new_hash = %old _hash; #两个hash顺序不一定完全相同
    my %hash = reverse %oldhash; #反转键值对,适用于键值都唯一的哈希,如主机名和IP
    

    哈希函数

    • keys函数返回键列表
    • values函数返回值列表
    my @k = keys %hash;
    my @v = values %hash;
    #返回键和值列表顺序是一一对应的。
    my $count = keys %hash; #3
    
    • each函数迭代哈希,返回键值对
    while( ($key, $value) = each %hash ){
        print "$key => $value\n";
    }
    #若要依次处理hash,需要对键进行排序
    foreach $key (sort keys %hash){
        $value = $hash{$key};
        print "$key => $value\n";
        #或print "$key => $hash{$key}\n";
    }
    
    • exists函数:检查哈希中是否存在某个键
    if($book{$someone}){ #判断hash元素真假
        print "$someone has at least one book checked out\n";
    }
    #这种情况下如果元素中本身含有0/undef等值,会错误判断。所以用exists函数。
    if(exists $book{'peng'}){
        print "peng has a library card\n";
    }
    
    • delete函数:从哈希中删除指定键及其对应的值
    my $person = "pjx";
    delete $books{$person}
    

    哈希元素内插

    foreach my $person (sort keys %books){
        if(exists $book{$person}){
            print "$person has $book{$person}\n";
        }
    }
    
    • %ENV哈希: 即PATH(环境变量)对应的值(路径)
      print "PATH is $ENV{PATH}\n";

    --------- 第七章 正则表达式----------

    简介

    1. 正则表达式是Perl内嵌的,自成一体的微型编程语言,如awk,sed,grep等语言以及vi,emacs等编辑器都带有正则表达,只是语法规则略有不同。
    2. 又称模式,查看一个字符串匹配或不匹配。
    3. 注意不要与shell中文件名通配(又称glob)混为一谈。

    简单模式

    默认匹配对象$_,则只要/chracter/即可

    $_ = "abdgewgaegggea";
    if(/dge/) {print "It matched\n";}
    

    模式匹配通常用来返回真假,所以常用于while/if等条件中。
    转义符/制表符等同样可以用于模式串中。

    元字符

    点号(.):匹配任意一个除换行符外的字符 (没有或超过一个都不行)。
    在任何元字符前加上反斜线即失去元字符的作用。如/3\.14/

    简单量词

    * 星号:匹配前面的0个或多个
    .* :匹配0到多个字符
    + 加号: 匹配一个或多个
    ? 问号:匹配0个或1个
    

    模式分组

    用小括号对字符串分组,如/(fred)+/
    反向引用捕获组:引用小括号中所匹配的字符,\1,\2

    $_= "abba";
    if(/(.)\1/) #匹配bb
    
    $_ = "yabba dabba doo";
    if(/y(....) d\1/) #匹配abba
    if(/y(.)(.)\2\1/) #回文模式 匹配abba
    if(/y((.)(.)\3\2) d\1/) #匹配模式顺序,从左到右半边括号依次对应123
    
    #反向引用的模式后接数字的情况:
    $_ = "aa11bb";
    if(/(.)\111/) #不知引用的是\1,\11,\111?
    #消除以上二义性: \g{N}
    if(/(.)g{1}11/)
    if(/(.)(.)\g{-1}11/) #负号
    
    $_ = "xaa11bb";
    if(/(.)(.)\g{-1}11/)
    

    择一匹配

    /fred(|\t)+barney/
    /fred(or|and)barney/

    字符集

    一个好的正则模式应只匹配到需要的那些字符,不留一点多余。

    [a-zA-Z] #[]匹配其中任何**一个**字符。  
    
    $_ = " The HAL-9298 requres";
    if (/HAL-[0-9]+/)
    
    #脱字符^,表不匹配
    [^def] 
    [^n\-z] #\转义
    
    #字符集的简写
    
    \d 数字: 近似于[0-9]
    \s 空白符:包括换页符/制表符/换行符/回车符/空格,即等于[\f\t\n\r]
    \w 单词字符(字母数字下划线):相当于[a-zA-Z0-9_]
    
    # 反义的简写
    \D:即[^\d]
    \W:即[^\w]
    \S:即[^\s]
    
    [\d\D] 匹配任何字符(包括换行符),比点号还广(不包括换行符)
    

    ----------- 第八章 正则匹配-----

    匹配

    m//m##等,省略为//##

    模式匹配修饰符

    /i 忽略大小写 if(/yes/i)
    /s 匹配任意字符
    #(一般用于含换行符的字符串)if(/barney.*fred/s)
    
    /x 加入空白符
    #(使之更加易读)if(/ -? [0-9]+ \.? [0-9]* /x)
    #还能添加注释:当然注释中不能含有/等定界符,否则视为模式终点
        /
            -?     #0或1个-
            [0-9]+    #至少1个数字
            \.?    #0或1个.
            [0-9]*    #至少0个数字
        /x    #字符串末尾
        
    if(/barney.*fred/is) 组合修饰符,与顺序无关
    

    字符串锚位(右斜线)

    \A 锚位字符串开头  m{\Ahttps?://}i
    \z 锚位字符串末尾  m{\.png\z}i
    \Z 行末锚位,即在锚位字符串末尾但允许后面出现换行符 /\.png\Z/
    /\A\s*\Z/ 组合匹配一个空行
    
    但最习惯的还是用脱字符^ $来锚位行的首尾。
    行的首尾和字符串的首尾有一点区别:字符串有可能是多行。
    但即使这样,我们仍倾向于用^$,只需后面加个修饰符/m即可。
    
    /^barney/m  #等于/\Abarney\Z/
    

    单词锚位

    \b 匹配单词的首尾,整词匹配. /\bfred\b/
    \B 非单词边界锚位。/\bsearch\B/ 匹配searching等
    

    绑定操作符

    模式匹配默认对象是$_,用 =~ 拿右边的模式来匹配左边的字符串。

    my $some = "this is a string";
    if($some =~ /\bstr/){print "yes\n";}
    

    捕获变量

    $1,$2,$3...类似反向引用的\1,\2,\3...,但反向引用是模式匹配期间的结果,而捕获变量是匹配结束后捕获内容的索引。

    $_ = "hello there, neighbor";
    if(/\s(\[a-zA-Z]+),/){ #匹配空白符和逗号间的单词
        print "the word was $1\n";
    }
    
    if(/(\S+) (\S+), (\S+)/){
        print "words are $1 $2 $3\n";
    }
    
    my $names = 'fred or barney';
    if($names =~ /(\w+) (or|and) (\w+)/){
        say "I saw $1 and $3";
    }
    

    捕获变量的存续期

    匹配才改变内容,不匹配还是原来的内容

    if($pjx =~ /([a-zA-Z]+)/){
        print "pjx is $1\n";
    }else{
        print "pjx have no word\n";
    }
    
    #复制给变量长期使用
    if($pjx =~ /([a-zA-Z]+)/){
        my $var = $1;
        ...
    }
    

    不捕获模式?:

    # 用?:来表示这对括号内只是分组,而非捕获
    if(/(?:bronto)?sarus (steak|buger)/){
        print "Fred wants a $1\n"; #捕获第二个括号
    }
    #建议尽可能用非捕获括号来分组
    

    自动捕获变量

    速度拖慢,常用于正则表达式中的替换操作

    $& 匹配内容
    $` 匹配区段前的内容
    $' 匹配区段后的内容
    
    if("hello there, neighbor" =~ /\s(\w+),/){
        print "that was $` $& $'.\n"; #分别对应原三个单词
    }
    

    通用量词

    /a{5,10}/ #匹配5-10个a
    /(fred){3,}/ #匹配3个以上fred
    /(ged){8}/ #刚好匹配8个
    

    --------- 第九章 用正则表达式处理文本 -----

    s///替换

    $_ = "he's out bowling with barney tonight";
    s/barney/fred/;
    print "$_\n";
    s/with (\w+)/against $1's team/; #替换为捕获
    print "$_\n";
    
    if(s/out/in/) #返回布尔值
    
    # 除s//外,其他定界符
    非成对字符  s#^https://#http://#;
    成对字符    s{fred}{barney};  s<fred>(barney)
    
    

    /g全局替换

    $_ = "home, sweet home!";
    s/home/cave/g;
    print "$_\n";
    
    #常用于缩减空白
    $_ = "input data\t may have    extra whitespace";
    s/\s+/ /g;
    
    #删除开头和结尾的空白
    s/^\s+//;
    s/\s+$//;
    s/^\s+|\s+$//g; #一次到位
    
    #其他替换修饰符
    /i 无关大小写  s/wilma/WILMA/gi
    /x 加入任何空白
    /s 任意字符(包括换行)
    
    

    绑定操作符

    $file_name =~ s/^.*//s;

    无损替换

    同时保留原始的和替换后的字符串

    my $original = 'fred ate 1 rib';
    my $original2 = 'fred ate 1 rib';
    (my $copy = $original) =~ s/\d+ ribs?/10 ribs/;
    #加括号先赋值后替换,返回成功替换的次数??
    my $copy2 = $original2 =~ s/\d+ ribs?/10 ribs/r;
    #不加括号先替换后赋值,加\r修饰符,返回替换的结果??
    print "$original\n$copy\n";
    print "$original2\n$copy2\n";
    
    #输出结果一样啊:
    fred ate 1 rib
    fred ate 10 ribs
    fred ate 1 rib
    fred ate 10 ribs
    

    大小写转换

    \U 其后所有字符转换成大写
    \L 其后所有字符转换成小写
    \u 其后第一个字符转换成大写
    \l 其后第一个字符转换成小写
    \E 关闭大小写转换
    
    $_ = "I saw Barney with Fred.";
    s/(fred|barney)/\U$1/gi;
    s/(fred|barney)/\L$1/gi;
    s/(\w+) with (\w+)/\U$2\E with $1/i;
    s/(fred|barney)/\u$1/gi;
    s/(fred|barney)/\u\L$1/gi; #首字母大写
    
    #注:以上转换方法同样可用在任何双引号内的字符串:
    print "\L\u$name\E, are you ok?";
    

    split操作符

    my @files = split /\s+/, $_; #等同于split/\s+/
    my @files = split/\t/, $_, 2; #只拆分为2段
    
    my @fields = split/:/, "ab:db::e"; # 会产生一个空字段
    my @fields = split /:/, "::ab:cd:::"; #前面的空字段保留,后面的会省去
    
    

    join函数

    与split相反

    my $result = join $glue, @pieces;  #glue可以是任意字符串
    my $x = join ";", 4,6,7,8,9;  # 4;6;7;8;9
    my $y = join "foo", "bar,gre"; #barfoogre
    my @value = split /;/, $x;
    my $z = join "-", @value; #4-6-7-8-9
    

    列表上下文中的匹配

    不要与上面的s///(返回次数)混淆了

    my $text = "fred a 5 ton Mr. Slate";
    my @words = ($text =~ /([a-z]+)/ig);
    print "result: @words\n"; #fred a ton Mr Slate
    
    my $data = "barney rubble fred Flid Wilm fint";
    my %name = ($data =~ /(\w+)\s+(\w+)/g); #每次捕获一对值,生成hash键值对
    

    非贪婪量词

    $test = "this the is a the is a test";
    $test =~ s/the (.*?) a/$1/g;
    
    +?
    *?
    {5,10}?
    {8,}?
    ?? #问号本身的非贪婪,即在0或1的情况下匹配0次
    

    跨行模式匹配

    /m

    Perl时间函数

    my $date = `date`;
    my $date = localtime;
    
  • 相关阅读:
    做一个:网页请求数据库数据 流程
    开始一个Django项目的简单方法
    Django模板系统
    Python Django 中的STATIC_URL 设置和使用解析
    Django框架(一)-Django初识
    bootstrap
    jQuery
    js(jquery)鼠标移入移出事件时,出现闪烁、隐藏显示隐藏显示不停切换的情况
    PHPCMS快速建站系列之网站迁移(本地到服务器,服务器迁移,更换域名等)
    PHPCMS快速建站系列之在线留言
  • 原文地址:https://www.cnblogs.com/jessepeng/p/10962651.html
Copyright © 2011-2022 走看看