regex - 如何找到字符串上正则表达式匹配的百分比?

标签 regex perl

<分区>

我参与了一项数字 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 语言编写的,性能要好得多。

关于regex - 如何找到字符串上正则表达式匹配的百分比?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40010113/

相关文章:

使用 perl() 时 MATLAB 内存不足

c - 代码中可能存在内存错误以及可能的解决方案?

php - 跨度正则表达式替换

perl - 有没有办法在Perl中强制无效上下文?

perl - 我可以在 Perl 中使用 sprintf 为数字指定最大精度宽度吗?

perl - 如何在不中继perd中的stdout的情况下做system()

database - 在 DBIx::Class 中设置操作

regex - PostgreSQL 检查约束不起作用

c# - 为什么我不能从 CaptureCollection 对象调用 Select()?

c# - 使用正则表达式获取引号内的文本