perl模式匹配单行模式与多行模式混合使用的一点内容

4150阅读 0评论2013-07-30 lanmeibanban
分类:PERL

今天见到一个表达式 $line =~ m/^@([^\n]+)$/xmso; 一直没搞懂是什么意思。翻了半天资料最后在《Perl cookbook》中找到了答案。
具体内容详见:《Perl cookbook 第二版》 第六章,第六节 (197页)或 第一版的相同章节。

我们知道perl可以自定义文件中行的分割符,虽然默认的是‘\n’,但是也可以一次将文件中的所有‘行’读入在一个字符串变量中。然后在对这个字符串变量进行模式匹配的分析。假设有文件内容如下:

%abcdef
12734832794912834789
%djenuiv
3748998585939190
...

如果一次读入在一个变量中,就是:

%abcdef\n12734832794912834789\n%djenuiv\n3748998585939190 ...

先说锚定符,如果在单行模式 /s 下使用^或$来表示匹配开始或末尾的话,那么^、$将匹配的是字符串的开头和末尾,而并不是以‘\n’为概念的行的开头和末尾,如果想匹配‘\n’为概念的行的开头和末尾,则要与多行模式混合 /m 使用,即 m/你的模式/sm,但是这还取决于另一个元字符——'.'。

再说下元字符'.',我们知道‘.’在模式匹配中表示任意字符。那么在混合模式下,如果你用m/^(.+)$/ms。你猜猜你得到的是什么,实际上是从字符串的开头到末尾的字符,而不是每行的内容,以上面的内容为例:

点击(此处)折叠或打开

  1. my $line = "\%abcdef\n12734832794912834789\n\%djenuiv\n3748998585939190"; #因为是直接写的字符串,所以要将%符号转义,否则会判断为哈希结构。
  2. $line =~ m/^%(.+)$/ms;
  3. print $1;
此时的输出为:
abcdef
12734832794912834789
%djenuiv
3748998585939190

实际是从字符串第一个%开始直到字符串末尾。

可是如果想匹配的是‘\n’分割的行内的任意字符怎么办呢?实际上就如最前面的例子一样,用[^\n]来代替这个‘.’。

修改下前面的例子:

点击(此处)折叠或打开

  1. my $line = "\%abcdef\n12734832794912834789\n\%djenuiv\n3748998585939190";
  2. $line =~ m/^%([^\n]+)$/ms;
  3. print $1;
现在输出结果为:
abcdef

如果将所有匹配的内容返回给数组的话:

点击(此处)折叠或打开

  1. my $line = "\%abcdef\n12734832794912834789\n\%djenuiv\n3748998585939190";
  2. my @match = $line =~ m/^%([^\n]+)$/msg;
  3. print join ',', @match;
结果如下:
abcdef,djenuiv

结束!




上一篇:sed新手使用进阶全功略
下一篇:Bioconductor对芯片探针信息进行注释