use strict;
use warnings;
while (<DATA>) {
while (m#/(\*?)(.*?)\1/#g) {
print "$2\n";
}
}
__DATA__
There are many who dare not kill themselves for [/fear/] of what the neighbors will say.
Advice is what we ask for when we already know the /* answer */ but wish we didn’t.
作为一个单行:
perl -nlwe 'while (m#/(\*?)(.*?)\1/#g) { print $2 }' input.txt
内部 while 循环将在所有带有/g
修饰符的匹配项之间进行迭代。反向引用\1
将确保我们只匹配相同的打开/关闭标签。
如果您需要匹配跨越多行的块,则需要 slurp 输入:
use strict;
use warnings;
$/ = undef;
while (<DATA>) {
while (m#/(\*?)(.*?)\1/#sg) {
print "$2\n";
}
}
__DATA__
There are many who dare not kill themselves for [/fear/] of what the neighbors will say. /* foofer */
Advice is what we ask for when we already know the /* answer */ but wish we didn’t.
foo bar /
baz
baaz / fooz
单线:
perl -0777 -nlwe 'while (m#/(\*?)(.*?)\1/#sg) { print $2 }' input.txt
-0777
开关 和将$/ = undef
导致文件 slurping,这意味着所有文件都被读入一个标量。我还添加了/s
修饰符以允许通配符.
匹配换行符。
正则表达式的解释:m#/(\*?)(.*?)\1/#sg
m# # a simple m//, but with # as delimiter instead of slash
/(\*?) # slash followed by optional *
(.*?) # shortest possible string of wildcard characters
\1/ # backref to optional *, followed by slash
#sg # s modifier to make . match \n, and g modifier
这里的“魔力”在于,*
只有在它之前找到一个星号时,反向引用才需要一个星号。