今天见到一个表达式 $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。你猜猜你得到的是什么,实际上是从字符串的开头到末尾的字符,而不是每行的内容,以上面的内容为例:
-
my $line = "\%abcdef\n12734832794912834789\n\%djenuiv\n3748998585939190"; #因为是直接写的字符串,所以要将%符号转义,否则会判断为哈希结构。
-
$line =~ m/^%(.+)$/ms;
-
print $1;
此时的输出为:
abcdef
12734832794912834789
%djenuiv
3748998585939190
实际是从字符串第一个%开始直到字符串末尾。
可是如果想匹配的是‘\n’分割的行内的任意字符怎么办呢?实际上就如最前面的例子一样,用[^\n]来代替这个‘.’。
修改下前面的例子:
-
my $line = "\%abcdef\n12734832794912834789\n\%djenuiv\n3748998585939190";
-
$line =~ m/^%([^\n]+)$/ms;
-
print $1;
现在输出结果为:
abcdef
如果将所有匹配的内容返回给数组的话:
-
my $line = "\%abcdef\n12734832794912834789\n\%djenuiv\n3748998585939190";
-
my @match = $line =~ m/^%([^\n]+)$/msg;
-
print join ',', @match;
结果如下:
abcdef,djenuiv
结束!
阅读(4086) | 评论(0) | 转发(0) |