[英]Matching a perl regular expression over multiple lines
好的,所以我還有另一個問題需要幫助,我需要使用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
然后它在此處打印換行符,而沒有其余信息
由於my @arr = /ADDRESS\\s*\\S*\\s\\S*\\s\\S*\\s\\S*\\s*\\n\\s*\\S*/g or next;
您只能得到一行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 ;
}
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",
},
]
對於初學者,您的樣本都沒有顯示多行。 因此,根據您的示例,我立即看不到如何為您提供幫助。
盡管通常這將是默認輸入記錄分隔符的問題。 這意味着Perl在處理文件時的默認行為是一次給您一行。 除非您為此做任何事情,否則您將永遠無法獲得想要的東西。
控制它的變量是$/
,因此假設FILE
是打開的文件句柄,則需要執行以下操作:
local $/;
my $contents = <FILE>;
現在, $contents
將文件的全部$contents
包含在單個字符串中,並嵌入所有"\\n"
。 這樣一來,您便可以實際嘗試比賽。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.