我有一个包含此类内容的文件:
*** X REGION ***
|-------------------------------------------------------------------------------------------------|
| X |
| addr tag extra data |
|-------------------------------------------------------------------------------------------------|
| $A1 label_A1X | 1 |
| $A2 label_A2X | 2 |
| $A3 label_A3X | 3 |
*** Y REGION ***
|-------------------------------------------------------------------------------------------------|
| Y |
| addr tag extra data |
|-------------------------------------------------------------------------------------------------|
| $0 label_0Y | 99 |
| $1 | 98 |
我需要在' addr'下捕获数据。和'标记&#39 ;;被逗号隔开; 单独以获取' X REGION'下的记录和' Y地区'。 这就是我的尝试:
open($fh1, "<", $memFile) or warn "Cannot open $memFile, $!"; #input file with contents as described above.
open($fh, "+<", $XFile) or warn "Cannot open $XFile, $!";
open($fh2, "+<", $YFile) or warn "Cannot open $YFile, $!";
while(my $line = <$fh1>)
{
chomp $line;
$line = $line if (/\s+\*\*\*\s+X REGION\s+\*\*\*/ .. /\s+\*\*\*\s+Y REGION\s+\*\*\*/); #Trying to get at the stuff in the X region.
if($line =~ /\s+|\s+\$(.*)\s+(.*)\s+|(.*)/)
{
$line = "$1,$2";
print $fh $line;
print $fh "\n";
}
my $lastLineNum = `tail -1 filename`;
$line = $line if (/\*\*\* Y REGION \*\*\*/ .. $lastLineNum); #Trying to get at the stuff in the Y region.
if($line =~ /\s+|\s+\$(.*)\s+(.*)\s+|(.*)/)
{
$line = "$1,$2";
print $fh2 $line;
print $fh2 "\n";
}
}
这表示$ 1和$ 2未初始化。正则表达式是不正确的?还有(还有)还有什么?
答案 0 :(得分:3)
这是一段代码,可以根据需要运行(充分利用默认的perl隐式var $_
):
# use die instead of warn, don't go ahead if there is no file
open(my $fin, "<", $memFile) or die "Cannot open $memFile, $!";
while(<$fin>)
{
# Flip flop between X and Y regions
if (/[*]{3}\h+X REGION\h+[*]{3}/../[*]{3}\h+Y REGION\h+[*]{3}/) {
print "X: $1,$2\n" if (/.*\$(\S*)\h*(\S*)\h*[|]/)
}
# Flip flop from Y till the end, using undef no need of external tail
if (/[*]{3}\h+Y REGION\h+[*]{3}/..undef) {
print "Y: $1,$2\n" if (/.*\$(\S*)\h*(\S*)\h*[|]/)
}
}
这是输出:
X: A1,label_A1X
X: A2,label_A2X
X: A3,label_A3X
Y: 0,label_0Y
Y: 1,
谈论你的代码有很多要解决的问题:
在你的正则表达式中选择管道|
需要转义的分隔符之间的元素:使用反斜杠\|
或char类[|]
(我更喜欢后者)< / p>
\s
也匹配换行符(严格\n
或回车\r
),不要将其用作一般空格加标签\t
替换。使用\h
(仅限水平空格)代替
您使用\s+
启动正则表达式,但在示例中,表格行的第一个字符始终为'|'
.*
除了换行符(\n
或\r
)
所以像.*\s+
这样的正则表达式匹配整行和新行(\s
)以及下一行中可能的空格
触发器perl运算符..
为您提供所选区域(包括边缘)中的行,但每次一行,因此转义的管道表单也是如此你的正则表达式:
\s+[|]\s+\$(.*)\s+(.*)\s+[|](.*)
所以我用这个替换了数据提取正则表达式:
.*\$(\S*)\h*(\S*)\h*[|]
正则表达式突破
.*\$ # matches all till a literal dollar '$'
(\S*) # Capturing group $1, matches zero or more non-space char [^\s]
# can be replaced with (\w*) if your labels matches [0-9a-zA-Z_]
\h* # Match zero or more horizontal spaces
(\S*) # Capturing group $2, as above
\h* # Match zero or more horizontal spaces
[|] # Match a literal pipe '|'