为啥 Perl v5.22 找不到所有的句子边界?

Posted

技术标签:

【中文标题】为啥 Perl v5.22 找不到所有的句子边界?【英文标题】:Why doesn't Perl v5.22 find all the sentence boundaries?为什么 Perl v5.22 找不到所有的句子边界? 【发布时间】:2016-08-18 09:03:04 【问题描述】:

这在 Perl 5.22.1 中已修复。我在Perl v5.22 adds fancy Unicode word boundaries 中写到。


Perl v5.22 添加了来自 TR #29 的 Unicode 断言。我一直在玩句子边界断言,但它似乎只找到文本的开头和结尾:

use v5.22;

$_ = "See Spot. (Spot is a dog.) See Spot run. Run Spot, run!\x2029New paragraph.";

while( m/\bsb/g ) 
    say "Sentence boundary at ", pos;
    

输出在文本的开头和结尾标注句子边界,但不在句号、句子终止符或括号之后:

Sentence boundary at 0
Sentence boundary at 70

Unicode breaks tester 主要显示它们,我希望它们基于 TR #29。

我在 perl 源代码中找不到此功能的任何重要测试。我正在消化技术报告以创建适当的测试用例,但到目前为止,这看起来像是另一个未经测试和损坏的功能。

【问题讨论】:

您使用的是哪个 Perl 版本? perldelta 手册页提到了 5.22.1 中 \bsb 的几个错误修复,当我使用该版本运行您的测试代码时,我在位置 0、10、27、41、56 和 70 处报告了句子边界。 @Calle Dybedahl:让该评论成为答案。我昨晚在编译 Perls 5.22.1 和 5.24 的 RC 时遇到了一些问题。 【参考方案1】:

Calle Dybedahl 的评论是正确的(当他们把它变成答案时,我会接受)。这是 v5.22.0 中的一个损坏功能,据我所知,未经测试。昨晚我在编译最新的 perls 时遇到了问题,并以问题结束了这一天。

perl5.22.1 perldelta 没有提及特定的更改(并且“提及”可能过于强烈,因为它只是暗示了可能的错误而不列举它们)。它提到与 5.20.0 不兼容的更改(剪切和粘贴错误?),“单个”异常,然后是多个问题。提到“理智”让我觉得所有的变化都与下一小节中的恐慌问题有关。仅在一个 rt.perl.org 参考中提到“几个错误”让我认为这些错误与恐慌问题有关。

=head1 不兼容的更改

没有故意与 5.20.0 不兼容的更改,除了 在一个例外之后,我们认为这是一个明智的改变 为了使新的 C 和(特别是) C 功能健全 在人们因为 Perl 5.22.0 中的错误而认为自己一文不值之前 实施并在未来避免它们。 如果存在任何其他问题,则它们是错误,我们要求您提交报告。 请参见下面的 L。

=head2 边界检查构造

已经修复了一些错误,包括分段错误 检查结构(在 Perl 5.22 中引入)C、C、C、 C、C 和 C。现在所有的 C 都匹配一个空的 细绳; C 没有一个。 Lhttps://rt.perl.org/Ticket/Display.html?id=126319>

此外,perlrebackslash,其中记录了新边界,并没有提到它们在 v5.22.0 中不起作用。

由于 perldelta 中的不协调以及我之前的经验是新功能没有在 perl 源代码中充分(甚至根本没有)测试,我忽略了可能的修复。我过早地中断了调查,本可以为自己节省几个小时。没有让代码在最新的二进制文件上运行当然是我的错,但我一直认为我做错了什么并且我的代码是问题所在。尽管我过去有很多相反的经历,但我并没有想到 perl 是错误的(除了对 UCD 的更新)。

现在我在另一台机器上并且有一个可以工作的 perl-5.22.1,我看到我的程序在点发布中按预期工作。 perldelta 在这里可能会更好。

【讨论】:

【参考方案2】:

这种情况主要归咎于我,但还有其他人,所以我将在下面的地方使用复数第一人称。

首先,当 5.22.1 的 perldelta 表示 5.20.0 时,它表示 5.22.0,这是一个错字。它只提到了一个问题,因为在我们看来它们只是一回事,Unicode 打破了界限。

这些是在 5.22 后期添加的,直到 5.22 发布后我们才意识到存在问题。当问题开始出现时,其中一些被证明是 Unicode 指定算法中的错误,我们假设所有问题都是这样。

但一切都经过了测试,我想,已经足够广泛了。最近的 Unicode 版本包括各种功能的发布测试,并且 5.22.0 通过了所有这些测试。您可以在 lib/unicore/TestProp.pl 中找到它们,它在每次“make test”完成时运行,由 t/re/uniprops.t 执行。这里有问题的由 Test_SB()(超过 500)和 Test_WB()(几乎 1500)调用,每个测试由几个子测试组成。这些测试比我自己想出的要多。

独立地,有人在 5.23 开发过程的早期报告了段错误。在对此进行调查时,通过阅读代码,我发现刚刚发布的代码中还有其他问题。交互很复杂,不容易总结,所以 perldelta 甚至没有尝试。这两种边界条件都需要跟踪可能出现边界的上下文,通常进行前瞻和/或后视。当代码通过目标字符串进行解析时,它会保存当前上下文以供下一次迭代,它将成为后视上下文,并且不必重新计算。这被破坏了,并且上下文并不总是被正确保存。这就是为什么 Unicode 提供的测试全部通过的原因。它们用于短输入,上下文中断无关紧要。当这一切都得到解决后,我惊喜地发现 \bsb 给出的结果比人类预期的要多。

Unicode 错误计划在 UAX #29 的下一个版本中修复,我认为我们做出了正确的决定,让 \bwb 和 \bsb 在 5.22.1 中工作。

【讨论】:

以上是关于为啥 Perl v5.22 找不到所有的句子边界?的主要内容,如果未能解决你的问题,请参考以下文章

我用 CPAN 成功安装了一个模块,但是 perl 找不到它。为啥?

为啥我的 Perl CGI 脚本找不到 Oracle DBD?

php句子边界检测[重复]

在 perl 中找不到路径

安装 Perl 模块时出现“致命错误:找不到‘EXTERN.h’文件”

perl的安装