3

簡単な概要... 家には、タンク内のオイル レベルを含むデータをシリアル ポート経由で出力するオイル タンク モニターがあります。ほとんどの場合、出力は一貫していますが、時間帯やランダムな「特別なイベント」では、わずかに異なるものを送信します。

これは、元のポート、改行などからダンプされた例です。

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 ! など...そして、これまでにないものは何もありません!!

これは、「ull」値が何であるか 100% もわからないため、現時点では一種の実験ですが、センサーからタンク内のオイルの表面までの距離であることを願っています! 時が教えてくれる。

4

1 に答える 1

0

これは、正規表現を完全な文字列と一致させようとしているためですが、そうではありません。そのull=(\d+)パターンを含む長い文字列には一致しません。そのパターンに完全に一致する文字列のみに一致します。

さらに、番号が確実に の場合length 3、正規表現で明示的に指定できます。+そこに数量詞は必要ありません。むしろ{3}数量詞、または0\d{2}あなたの番号が で始まるので0iそして、方法で一致するためのフラグを追加しcase-insensitiveます。

これを使ってみてください: -

if ($line =~ m!.*?ull=(0\d{2}).*!i)
于 2012-11-20T19:08:09.543 に答える