我参与了一项数字 radio 传播研究,其中远程发射器在定义的时间发送预定义的信标,该信标很容易与正则表达式匹配。
但由于太阳和大气条件,它并不总是 100% 解码。我想做的是计算解码的百分比。
信标格式如下:
de va6shs va6shs va6shs Loc DO46gs Olivia-4-250 NBEMS test 2218Z
| | | |
(Station) (Location) (Digital Mode) (UTC Time)
我真的可以用 Perl 算出百分比,还是我应该寻找其他解决方案?
编辑:由于我们使用的数据模式中的纠错有限,所以经常发生的情况是随机字符经常出现在解码字符串中,或者字符根本没有解码这些都是在不同时间从同一站接收到的字符串同一天太阳条件恶化。
100% decode
de ve6rfm ve6rfm ve6rfm Loc DO46gs Olivia-4-250 NBEMS test 0218Z
93.75%
P!de ve6rfm ve6rfm ve6rfm Loc DO46gs Olivia-4-250 NBEMS <TAB>est F248Z
9.375%
de ve6rfmr&
两个信标字符串之间的唯一区别应该是字符串末尾的 UTC 时间,但如您所见,有一些字符未正确解码。
正确解码的字符串有 64 个字符。
第一个错误解码的字符串有 60 个正确的字符。
所以 60/64 * 100 = 93.75% 解码。
我的电台呼号正则表达式,三个重复的词是
/[vV][aAeEyY][15678]\w{2,3}/
加拿大西部的研究涉及多个不同的电台,因此我需要在传播允许的情况下捕获它们,并且使用上述正则表达式使我不必在每次新电台播出时都更新我的脚本。
问题是部分匹配或模糊匹配。那里有一些模块可能会有所帮助。他们主要使用Levenshtein 距离,即从一个字符串中获取另一个字符串所需的编辑次数,但还有其他方法。请参阅 Text::Levenshtein 中的部分列表.参见 this post用于提供更多内容的搜索词组。
以下是使用 String::Approx 的示例, String::Similarity , 和 Text::Fuzzy .没有一个能准确给出您的要求,但都可以检索相似的测量值,并且具有可以让您获得目标的选项。
use warnings 'all';
use strict;
my $beacon =
'de va6shs va6shs va6shs Loc DO46gs Olivia-4-250 NBEMS test 2218Z';
my $received =
'P!de ve6rfm ve6rfm ve6rfm Loc DO46gs Olivia-4-250 NBEMS <TAB>est F248Z';
# Can use an object, or the functional interface
use Text::Fuzzy qw(fuzzy_index distance_edits);
my $tf = Text::Fuzzy->new ($beacon);
my ($offset, $edits, $distance);
# Different distance/edits
$distance = $tf->distance($received);
($offset, $edits, $distance) = fuzzy_index ($received, $beacon);
($distance, $edits) = distance_edits ($received, $beacon);
# Provides "similarity", in terms of edit distance
use String::Similarity;
my $similarity = similarity $beacon, $received;
# Can be tuned, but is more like regex in some sense. See docs.
use String::Approx qw(amatch);
my @matches = amatch($beacon, $received); # within 10%
# amatch($beacon, ["20%"], $received); # within 20%
# amatch($beacon, ["S0"], $received); # no "substitutions"
请查看他们的文档。
String::Approx
如果长度不超过 10%,则认为是“匹配”。这是默认值,模块允许调整该参数。例如,
amatch($beacon, ["20%"], $received);
将达到 20%。可以对您的可能用途进行其他改进。
该模块的较新版本是用 C 语言编写的,性能要好得多。