我是perl编程的新手,想了解用perl解析文本文件。 我有一个文本文件,其中包含不规则格式,我想将其解析为三个。
基本上该文件包含与以下内容类似的文本:
;out;asoljefsaiouerfas'pozsirt'z
mysql_query("SELECT * FROM Table WHERE (value='true') OR (value2='true') OR (value3='true') ");
1234 434 3454
4if[9put[e]9sd=09q]024s-q]3-=04i
select ta.somefield, tc.somefield
from TableA ta INNER JOIN TableC tc on tc.somefield=ta.somefield
INNER JOIN TableB tb on tb.somefield=ta.somefield
ORDER by tb.somefield
234 4536 234
并且列表以这种格式继续。
所以我需要做的是解析三个。即顶部的那个,获得哈希检查。第二个是mysql查询,第三个是解析这三个数字。出于某种原因,我不知道如何做到这一点。我在perl中使用'open'函数来从文本文件中获取数据。然后我尝试使用'split'函数进行换行,但结果是查询不在一行或一个模式中,所以我不能像我想象的那样使用它。
答案 0 :(得分:6)
假设:
use strict;
use warnings;
use English qw<$RS $OS_ERROR>;
local $RS = "\n\n";
open( my $fh, '<', $path_to_file )
or die "Could not open $path_to_file! - $OS_ERROR"
;
while ( <> ) {
chomp;
my ( $hash_check_line
, @inner_lines
)
= split /\n/
;
my @numbers = split /\D+/, pop @inner_lines;
my $sql = join( "\n", @inner_lines );
...
}
通过将$RS
($/
或$INPUT_RECORD_SEPARATOR
)更改为双换行符,我们会更改记录的读取方式。
这并不是那么奇怪,但在我使用Perl的那些年里,我不得不将记录分隔符设置为一些非常有趣的字符串,但有时只需要读取您想要读取的块即可。
答案 1 :(得分:3)
哦,天啊。
我看到的算法是:
考虑到这一点,我提出以下代码:
open my $fh, '<', $path_to_file
or die "Can't open $path_to_file: $!";
while (my ($checksum, $query, $numbers) = read_record($fh) ) {
# do something with record
}
close $fh or warn "$!";
sub read_record {
my $fh = shift;
my @lines;
LINE: while (my $line = <$fh>) {
chomp $line;
last LINE if $line eq q{}; # if empty, we're done with the record!
push @lines, $line; # store it :)
}
return unless @lines; # if we didn't get anything, eof!
my $checksum = shift @lines; # first was checksum.
my $numbers = pop @lines; # last thing read was numbers.
my $query = join ' ', @lines; # everything else, query.
return ($checksum, $query, $numbers);
}
当然,修改以适应边界条件。
答案 2 :(得分:2)
以下似乎有效:
while ($file_content =~ /\s*^(.+?)^(.*?)^(\d+\s+\d+\s+\d+)$/smg) {
my $checksum = $1;
my $query = $2;
my $numbers = $3;
# do stuff
}
以下是正则表达式的解释:
\s* # eat up empty lines
^(.+?) # save the checksum line to group 1
^(.+?) # save one or multiple query lines to group 2
^(\d+\s+\d+\s+\d+)$ # save number line to group 3
第一组总是只有一行,因为当遇到下一行时它是懒惰的,正则表达式会尝试在第二组开始匹配。此时,如果匹配的其余部分可以完成,则第二组将包含数字之前的所有后续行。