perl中的字符串解析
string parsing in perl
我需要一些有关在 perl 中进行字符串解析的帮助。
我有一个 http 服务器,它响应如下:
<html>
<head><title></title></head><body>
T:17.10;H:32.10
</body></html>
我需要捕捉这两个数字(在示例 17.10 和 32.10 中)并将它们放入两个变量中,我将使用它们来执行一些 if...then...else 循环。
我不太擅长字符串操作和正则表达式,目前我正在尝试这样做:
my $url = 'http://192.168.25.9';
my $content = get $url;
die "Couldn't get $url" unless defined $content;
my @lines = split /\n/, $content;
$content2 = $lines[2];
$content2 =~ tr/T://d;
$content2 =~ tr/H://d;
my @lines2 = split /;/, $content2;
$tem = $lines2[0];
$hum = $lines2[1];
$tem =~ m{(\d+\.\d+)};
$hum =~ m{(\d+\.\d+)};
但是当我打印出该行时,我看到了一些奇怪的东西:缺少字符,该行中有 space 等。
好像我有一些奇怪的隐形字符造成混乱。
你能建议我一个更好的方法来将两个数字放在两个数字变量中吗?
谢谢
法比奥
一个完整的解决方案,避免使用 REGEX 解析 HTML(参考:RegEx match open tags except XHTML self-contained tags
) :
use strict; use warnings;
# base perl module to fetch HTML
use LWP::UserAgent;
# base perl module to parse HTML
use HTML::TreeBuilder;
# fetching part
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => "http://192.168.25.9");
my $res = $ua->request($req);
die $res->status_line, "\n" unless $res->is_success;
# parsing part
my $tree = HTML::TreeBuilder->new();
# get text from HTML
my $out = $tree->parse($res->decoded_content)->format;
# extract the expected string from the text output
if ($out =~ /^\s*T:(\d{2}\.\d{2});H:(\d{2}\.\d{2}).*/) {
print join "\n", , ;
}
输出:
17.10
32.10
对于此类请求,您可以这样做:
my ($t, $h) = map { (/T:(\d+|\d+.\d+);H:(\d+|\d+.\d+)/)?(, ):() } @req;
print "$t, $h\n", $t * $h;
输出:
17.10, 32.10
548.91
其中 @req
是一个包含接收到的请求的压缩字符串的数组
为了您的目的,这就是您所需要的:
my ($tem, $hum) = $content =~ /T:(\d{2}\.\d{2});H:(\d{2}\.\d{2})/;
如果您需要更通用的解析(例如,支持 >= 100 的温度或湿度、单个数字值等...):
my ($tem, $hum) = $content =~ /T:(\d+(?:\.\d+)?);H:(\d+(?:\.\d+)?)/;
我需要一些有关在 perl 中进行字符串解析的帮助。 我有一个 http 服务器,它响应如下:
<html>
<head><title></title></head><body>
T:17.10;H:32.10
</body></html>
我需要捕捉这两个数字(在示例 17.10 和 32.10 中)并将它们放入两个变量中,我将使用它们来执行一些 if...then...else 循环。
我不太擅长字符串操作和正则表达式,目前我正在尝试这样做:
my $url = 'http://192.168.25.9';
my $content = get $url;
die "Couldn't get $url" unless defined $content;
my @lines = split /\n/, $content;
$content2 = $lines[2];
$content2 =~ tr/T://d;
$content2 =~ tr/H://d;
my @lines2 = split /;/, $content2;
$tem = $lines2[0];
$hum = $lines2[1];
$tem =~ m{(\d+\.\d+)};
$hum =~ m{(\d+\.\d+)};
但是当我打印出该行时,我看到了一些奇怪的东西:缺少字符,该行中有 space 等。 好像我有一些奇怪的隐形字符造成混乱。
你能建议我一个更好的方法来将两个数字放在两个数字变量中吗?
谢谢 法比奥
一个完整的解决方案,避免使用 REGEX 解析 HTML(参考:RegEx match open tags except XHTML self-contained tags ) :
use strict; use warnings;
# base perl module to fetch HTML
use LWP::UserAgent;
# base perl module to parse HTML
use HTML::TreeBuilder;
# fetching part
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => "http://192.168.25.9");
my $res = $ua->request($req);
die $res->status_line, "\n" unless $res->is_success;
# parsing part
my $tree = HTML::TreeBuilder->new();
# get text from HTML
my $out = $tree->parse($res->decoded_content)->format;
# extract the expected string from the text output
if ($out =~ /^\s*T:(\d{2}\.\d{2});H:(\d{2}\.\d{2}).*/) {
print join "\n", , ;
}
输出:
17.10
32.10
对于此类请求,您可以这样做:
my ($t, $h) = map { (/T:(\d+|\d+.\d+);H:(\d+|\d+.\d+)/)?(, ):() } @req;
print "$t, $h\n", $t * $h;
输出:
17.10, 32.10
548.91
其中 @req
是一个包含接收到的请求的压缩字符串的数组
为了您的目的,这就是您所需要的:
my ($tem, $hum) = $content =~ /T:(\d{2}\.\d{2});H:(\d{2}\.\d{2})/;
如果您需要更通用的解析(例如,支持 >= 100 的温度或湿度、单个数字值等...):
my ($tem, $hum) = $content =~ /T:(\d+(?:\.\d+)?);H:(\d+(?:\.\d+)?)/;