阅读笔记-精通正则表达式-第2章-入门示例及扩展-2

5. 使用环视功能为数值添加逗号

    四种类型的环视:
    · 肯定逆序环视    (?<= ......)      子表达式能够匹配左侧的文本
    · 否定逆序环视    (?<!  ......)      子表达式不能匹配左侧的文本
    · 肯定顺序环视    (?= ......)        子表达式能够匹配右侧的文本
    · 否定顺序环视    (?!  ......)        子表达式不能匹配右侧的文本
     对于肯定顺序环视,从左至右查看文本,尝试匹配子表达式,如果能够匹配,就返回匹配成功信息。例如:(?=/d)表示如果当前位置右边的字符是数字则匹配成功。对于肯定逆序环视,从右至左查看文本。
     需要注意的是,四种环视匹配的都是位置,而不是某个字符。比如:对于字符串"Jeffrey",表达式"(?=rey)"表示匹配右边是rey的位置,即Jeff与ref之间的位置。对与这个位置,如果使用字符串修改功能,就实现了对字符串的信息添加。
     $value =~ s/(?:\d)(?:\d\d\d)+$/,/g    匹配的位置为:左侧是数字,右侧到结束位置数字个数正好是3的倍数。
     以数字12345678为例:第一次匹配到2与3之间的位置,12,345678,第二次匹配到5与6之间的位置,12,345,678。
     有一种匹配$value =~ s/(\d)(\d\d\d)+$/$1,$2/g,注意这个表达式,第一次匹配到的是12345678这个整个字符串,$1=12,$2=345678,修改后为12,345678,由于第一次直接匹配到了整个字符串,所以匹配结束了,这里与环视的匹配有很大的不同,环视匹配只匹配到那个位置。

6. Text-to-HTML转换

    通过这个例子,发现原来正则表达式还可以写的错落有致。代码如下:   

undef  $ / ;   #  进入“文件读取”模式
$text   =<> #  读取命令行中指定的第一个文件名
$text   =~  s /&/& amp; / g;     #  把基本的HTML
$text   =~  s /</& lt; / g;      #  字符&、<和>
$text   =~  s />/& gt; / g;      #  进行HTML转义

$text   =~  s /^\ s * $ /< p >/ mg   #  划分段落

# 转换为链接形式

$text   =~  s{
  
\ b
  
#  把地址保存到$1
  {
    
\ w[ -.\ w] *                                  #  username
     \ @                   
    [ - a - z0 - 9 ] + ( \. [ - a - z0 - 9 ] + ) *\. (com | edu | info)  #  hostname 
  }
  
\ b
}{
< a href = " mailto:$1 " > $ 1 </ a > }gix

print   $text # 最后,显示HTML文本

    · $text =~ s/^\s*$/<p>/mg  # 划分段落
      /g是全局匹配符
      /m是增强行锚点,即^和$会从字符串模式切换到逻辑行模式,即对于字符串模式,一个文本只能有一个开始^和一个结束$,但是在逻辑行模式中,其中的每个行都会有各自的开始^和结束$。
    · $text =~ s{regex}{replacement}modifier
      实际上,Perl支持用户自定义分割符,默认是 s/.../.../,也可以定义为s{...}{...},或者S|...|...|
      对于s{...}{...}由于分割符不选取了{},“/”就不再作为分割符了,因此</a>中的“/”就可以直接使用了,不必进行转义了。
    · /x修饰符
      代码中的正则表达式如果不进行换行就会很长,读起来,注释起来都很麻烦,/x修饰符使得用户能够以“宽松排列”编排这个表达式,增强可读性。而且允许在表达式中出现,以#开头标记的注释。加上/x修饰符后,表达式中的空白字符就都变为“忽略自身”元字符。如果要用普通的空格等字符,可以对其进行转义,不转义的话,就是被忽略的元字符,此外\s总是能够匹配空白字符,这一点是没有变的。
    · 总结
    由于HTML标签中有很多</a>之类的标签,使用s{...}{...}可以省去对/的转义
    当正则表达式很长的时候,/x使得表达式可以换行且可以加入注释
    当需要匹配逻辑行的时候,/m使得^和$可以匹配逻辑行的开始和结束。

7. 处理重复单词

    要求将每句话中连续重复出现的单词进行高亮显示,并且如果某该行有重复单词出现,在该行的开始标出重复出现单词所在的文件。

$ /   =   " .\n " #  设定特殊的“块模式”;一块文本的终结为点号和换行号的结合体

while ( <>
{
  
next   unless  {
      
#  匹配一个单词:
        \ b               #  单词的开始位置
       ( [a - z] +  )       #  单词存储在$1
      # 匹配单词后面的任意多个空白字符和/或tag

      (                #  空白存储在$2
          ( ?:
              
\ s           #  空白字符
               |             #  |
               < [ ^> ] +>       #  <TAG>形式的tag
           ) +           #  至少需要出现一次
      )
      
#  再次匹配第一个单词
       ( \ 1 \ b)
  }
  
#  上面是正则表达式,下面是replacement字符串,然后是修饰符、/i、/g和/x
  { \ e[7m$ 1 \ e[m$ 2 \ e[7m$ 3 \ e[m}igx
  s
/^ ( ?: [ ^\ e] *\ n) +// mg;  #  去掉所有未标记的行
  s /^/ $ARGV :    / mg;       #  在每行开头加上文件名
   print ;
}

    · $\ = “.\n”
      这里的$\是特殊变量,一起一行是通过换行符决定的,比如\n,这样快模式下,是通过.\n决定的。这样一句话可能跨越多个行。
    · while(<>)和print
      <>能够将字符串赋值给一个特殊的变量,并且这个变量保存了s/.../...和print作用的默认字符串 。
    · next unless代表如果当前代码块没有执行,代码块下面的代码也不必执行,类似于if() {} else continue;(C++中)
    · {\e[7m$1\e[m$2\e[7m$3\e[m}igx
      \e[7m是高亮字符的起始标记,\e[m是高亮字符的终止标记。
    · s/^(?:[^\e]*\n)+//mg;
      由于有重复单词的行中都嵌入了高亮标记代码,这里只要找到没有高亮标记的行,然会替换为空就可以实现删除没有重复单词的行乐。
    · s/^/$ARGV:  /mg;      # 在每行开头加上文件名
      ARGV提供了输入文件的名字
    · 总结
      代码直接来自书中,实际能否正常运行没有实际测试,不能保证。不过代码本身介绍了很多的知识,尤其是/m、/x修饰符,加上以前的/g、/i修饰符,对正则表达式的了解加深了。

8. 总结

    第二章通过一些例子,展示了很多正则的具体内容,对PERL也进行了一定的介绍。现在学到了很多知识:元字符含义,转义,$text =~ m/.../.../... $text =~  s/.../.../...,修饰符:/i、/g、/m、/x,环视功能等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值