好的我还有另一个问题需要帮助我需要使用perl在txt文件中收集地址,我有一个地方可以从文件中的每个单独的票据中获取地址。我的问题是地址延伸的多行。我可以让它抓住第一线,但无论我做什么,它都不会抓住下一条线。
示例文本文件
NAME Sprinkle, Jonathan U ADDRESS 16887 36 St NW
Calgary, AB T8O 0B0
带公寓的示例文本文件
NAME Nguyen, Michael S ADDRESS 100A
8447 149 Ave NW
Sherwood Park, AB T6J 0Z0
我需要能够处理带有公寓号码的地址以及没有公寓号码的房子
到目前为止我的代码(这只能抢到第一行):
if (/ADDRESS/){
my @arr = /ADDRESS\s*\S*\s\S*\s\S*\s\S*\s*\n\s*\S*/g or next;
print "$_\n" for @arr;
}
这给出的输出是:
ADDRESS 16887 36 St NW
然后它在这里打印一个换行符,而没有剩下的信息
答案 0 :(得分:1)
由于my @arr = /ADDRESS\s*\S*\s\S*\s\S*\s\S*\s*\n\s*\S*/g or next;
每次迭代,您只得到一行,您将数组设置为等于上一次模式匹配。您需要使用push
附加到该行,如下所示:
数据强>
NAME Sprinkle, Jonathan U ADDRESS 16887 36 St NW Calgary, AB T8O 0B0
NAME Nguyen, Michael S ADDRESS 100A 8447 149 Ave NW Sherwood Park, AB T6J 0Z0
<强> EX:强>
use strict;
use warnings;
my @addresses;
while ( $test =~ /ADDRESS\s*([A-Za-z0-9,[:blank:]]+)/gxm ) {
push @addresses, $1 ;
}
答案 1 :(得分:1)
OP注意:如果您提供的不仅仅是一条数据记录,它将有助于解决此类问题。
但是,当我们合并两个数据示例时,NAME和ADDRESS字段显然是垂直对齐的。这提供了一种相当简单的解析方法,因为我们基本上只需要匹配一个精确的正则表达式:
NAME Sprinkle, Jonathan U ADDRESS 16887 36 St NW
Calgary, AB T8O 0B0
NAME Nguyen, Michael S ADDRESS 100A
8447 149 Ave NW
Sherwood Park, AB T6J 0Z0
使用它作为基线,以下脚本可用于解析四个记录:
use warnings;
use strict;
my @records;
while (<DATA>) {
if (/^NAME (.{22})ADDRESS (.*)/) {
push @records, {
name => $1,
address => $2,
};
} elsif (/^\s{43}(.*)/) {
$records[-1]{address} .= "\n$1";
} else {
warn "Unknown format on $.: $_";
}
}
# Strip extra spacing from all fields
for (@records) {
for (values %$_) {
s/\s+$//mg;
}
}
# Output records for debugging
use Data::Dump;
dd \@records;
__DATA__
NAME Sprinkle, Jonathan U ADDRESS 16887 36 St NW
Calgary, AB T8O 0B0
NAME Nguyen, Michael S ADDRESS 100A
8447 149 Ave NW
Sherwood Park, AB T6J 0Z0
NAME Sprinkle, Jonathan U ADDRESS 16887 36 St NW
Calgary, AB T8O 0B0
NAME Nguyen, Michael S ADDRESS 100A
8447 149 Ave NW
Sherwood Park, AB T6J 0Z0
输出:
[
{
address => "16887 36 St NW\nCalgary, AB T8O 0B0",
name => "Sprinkle, Jonathan U",
},
{
address => "100A\n8447 149 Ave NW\nSherwood Park, AB T6J 0Z0",
name => "Nguyen, Michael S",
},
{
address => "16887 36 St NW\nCalgary, AB T8O 0B0",
name => "Sprinkle, Jonathan U",
},
{
address => "100A\n8447 149 Ave NW\nSherwood Park, AB T6J 0Z0",
name => "Nguyen, Michael S",
},
]
答案 2 :(得分:0)
对于初学者,你的两个样本都没有显示多行。所以我马上就看不出如何根据你的例子来帮助你了。
大多数情况下,这将是默认输入记录分隔符的问题。这意味着Perl在处理文件时的默认行为是一次为您提供一行。除非你为此做些什么,否则你永远不会得到你想要的东西。
控制它的变量是$/
,因此假设FILE
是您的打开文件句柄,您需要执行以下操作:
local $/;
my $contents = <FILE>;
现在$contents
将文件的全部内容包含为嵌入了所有"\n"
的单个字符串。那么你实际上可以尝试你的比赛。