【问题标题】:Perl Regex to grab data from irregular serial port outputPerl Regex 从不规则的串口输出中获取数据
【发布时间】:2012-11-20 19:05:37
【问题描述】:

简要概述...我家里有一个油箱监视器,它通过串行端口输出数据,包括油箱中的油位。在大多数情况下,输出是一致的,但在每小时和随机“特殊事件”中,它发送的内容略有不同。

这是一个从端口、换行符等转储的示例。

20:23,Ull=000
20:24,Ull=000

RX:033 CMs,048 *F
20:25,Ull=000
20:26,Ull=000
20:29,Ull=000
RX:033 CMs,051 *F (Fast)
Chosen:0,Hour:10,033 CMs,051 *F

RX:033 CMs,051 *F (Fast)
Chosen:0,Hour:10,033 CMs,051 *F
20:34,ull=000

我想从此输出中提取的是 'ull=' 后面的数字,在这种情况下为 000,但该数字始终是 3 位整数,并且始终具有前导 0,即。 “033”或“001”或“259”

当它不是以 'HH:MM,ull=nnn' 格式发送时,可以忽略输出,因为它最多只持续 10 分钟,然后再次返回标准输出

使用我的电力监视器作为模板,它在类似的基础上工作,但我想出了更一致的输出......

#!/usr/bin/perl -w

# Read data from oil tank sensor via USB-serial port.

use strict;
use Device::SerialPort qw( :PARAM :STAT 0.07 );
use WWW::Mechanize;

open STDERR, '>/dev/null';

my $PORT = "/dev/ttyUSB2";
my $ob = Device::SerialPort->new($PORT);
$ob->baudrate(115200);
$ob->write_settings;

open(SERIAL, "+>$PORT");
while (my $line = <SERIAL>) {
    if ($line =~ m!ull=(\d+)!) { # trying and failing to extract the data on this line

my $oil = $1*1234;              # once the value is successfully captured I'll process
                                # it and send it for viewing & storage on the internet.


#send the oil volume value to emoncms (this section works ok.)
my $ua = WWW::Mechanize->new();
my $url = "http://emoncms.org/input/post?json={oil:$oil}&apikey=MY API KEY";
my $response = $ua->get($url);

    }

}

这只是一直在后台运行。

我认为可能是字符串中的 ',' 或 '=' 让我感到困惑,因为我可以将字符串的其他随机部分放入变量中,但绝不是我需要的值。任何帮助将不胜感激,因为我似乎使用了我能想到的所有随机符号组合 {} * .!m\//g /\n !等等......还有什么都无济于事!

目前这是一种实验,因为我什至不能 100% 确定“ull”值是多少,但我希望它是从传感器到油箱中油表面的距离!时间会证明一切。

【问题讨论】:

  • +1 用于将设备集成到油箱上,等等

标签: regex perl serial-port data-processing


【解决方案1】:

那是因为您试图将您的正则表达式与完整的字符串匹配,但事实并非如此。由于ull=(\d+) 不会匹配包含该模式的长字符串。它只会匹配完全匹配该模式的字符串。

此外,如果您的号码肯定是length 3,那么您可以在正则表达式中明确指定。你不需要+ 量词。而是{3} 量词,或0\d{2},因为您的号码以0 开头。并添加i 标志以case-insensitive 方式匹配。

尝试使用这个:-

if ($line =~ m!.*?ull=(0\d{2}).*!i)

【讨论】:

  • 可能想在该匹配项上添加不区分大小写的标志
  • @AnthonyLedesma .. 当然。补充说:)
  • 快速反应的好家伙!我仍然认为'='给我带来了问题(即使它不是官方的'特殊字符?')所以不得不去......($line =~ m!.*?ull.*(\d{ 3}).*!i)) 将 '=' 替换为 '.*' 以使其工作。我也想念我的问题,因为如果需要填充到 3 位数,该数字只有前导“0”,(即 003 需要零,但 342 不需要,因为它已经是 3 位数)因此我使用了 (\d{ 3}) 而不是 (0\d{2}) 但您非常敏锐地为我提出的问题提供最有效的答案!再次感谢,我的项目现在可以继续......克里斯
  • @user1631710.. 也许你可以尝试逃避它。因此,它不被视为元字符,但在look ahead 匹配中用作(?=...)。所以可能是因为这个原因它不起作用。
  • 对不起,我提交的第一个答案已经完成了一半!
猜你喜欢
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 2011-12-08
  • 1970-01-01
  • 2017-04-15
  • 1970-01-01
相关资源
最近更新 更多