是否有一些技巧可以与<>
进行多行正则表达式匹配,并循环它们?对于以\n
作为换行符分隔符的文件运行时,此示例不会导致匹配:
while (<> =~ m/\n./) {
print($.);
}
我需要知道while
循环内匹配开始的行,如示例所示。
目标是找到所有小于75个字符的行,后面跟一个以空格开头的行(标准的vCard分割长行的方式):
while (<> =~ m/(^|\n).{0,74}\n /)
答案 0 :(得分:6)
你在那个正则表达式中要做什么?看起来你试图找到一个换行符后面跟着至少一个字符的任何情况,然后这会导致你打印出符合该标准的行号($.
)。
如果你不介意我的问题,这里的目的是什么?
在任何情况下,请参阅此文章,以清楚地讨论多行匹配:Regexp Power
在转移到SO后编辑:如果您真正想要的是找到少于75个字符的行和以空格开头的下一行,我不会不要使用一个正则表达式。该描述指出了一种更简单,更清晰(我认为)的解决方案:(1)过滤掉少于75个字符的所有行(length
函数对此有利)。对于剩余的行,(2)检查下一行是否以空格开头。这为您提供了清晰的逻辑和易于编写的正则表达式。
回答关于获得“下一行”的问题。反过来想想:你想检查每个 next 行,但前提是之前的行少于75个字符。那怎么样:
my $prev = <>; # Initialize $prev with the first line
while (<>) {
# Add 1 to 75 for newline or chomp it perhaps?
if (length $prev < 76) {
print "$.: $_" if $_ =~ m/^\s/;
}
$prev = $_;
}
(请注意,我对vCard格式一无所知,并且\s
比字面上的“单个空格”更广泛。所以您可能需要调整该代码以更好地适应您的问题。)
答案 1 :(得分:5)
您是否记得通过将$/
设置为空字符串或未定义的值来将句柄置于多行模式?
以下程序可以满足您的需求:
#! /usr/bin/perl
use warnings;
use strict;
$/ = "";
*ARGV = *DATA;
while (<>) {
while (/^(.{0,75}\n(^[ \t].{1,75}\n)*)/mg) {
my $vcard = $1;
$vcard =~ s/\r?\n[ \t]//g;
print $vcard;
}
}
__DATA__
DESCRIPTION:This is a long description that exists on a long line.
DESCRIPTION:This is a long description
that exists on a long line.
DESCRIPTION:This is a long descrip
tion that exists o
n a long line.
输出:
$ ./try DESCRIPTION:This is a long description that exists on a long line. DESCRIPTION:This is a long description that exists on a long line. DESCRIPTION:This is a long description that exists on a long line.
答案 2 :(得分:3)
你有一个文件与vCards混合的任意文字?
如果您拥有的是一堆vCard文件并且想要解析它们,那么有一些vCard parsing modules on CPAN。
例如,请参见Text::vCard,特别是Text::vCard::Addressbook。
关于,
while (<> =~ m/\n./) {
print($.);
}
这确实不匹配任何东西,因为输入是逐行读取的简单事实意味着在换行符之后$_
中没有任何内容。
如果,每行短于76个字符后,永远不会超过单个延续行,以下内容可能符合以下要求:
#!/usr/bin/perl
use strict; use warnings;
for
(
my $this = <>, my $next = <>;
defined ($next = <>);
close ARGV if eof
)
{
printf "%s : %d\n", $ARGV, $. - 1 if 76 > length $this and $next =~ /^ /;
}