为什么Perl v5.22没有找到所有句子边界?

时间:2016-04-25 05:32:41

标签: regex perl unicode

这在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!\x{2029}New paragraph.";

while( m/\b{sb}/g ) {
    say "Sentence boundary at ", pos;
    }

输出会在文本的开头和结尾处记录句子边界,但不会在完整句点,句子终止符或parens之后记录句子边界:

Sentence boundary at 0
Sentence boundary at 70

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

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

2 个答案:

答案 0 :(得分:4)

Calle Dybedahl的评论是正确的(当他们把它变成答案我会接受的)。这是v5.22.0中的一个特性,据我所知,未经测试。我昨晚有一个问题汇编了最新的perls,结束了这一天的问题。

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

  

= head1不兼容的更改

     

除了5.20.0之外,没有任何故意与5.20.0不相容   遵循单一例外,我们认为这是一个明智的改变   为了获得新的C< \ b {wb}>和(特别是)C< \ b {sb}>功能健全   之前人们认为他们因为Perl 5.22.0中的漏洞而毫无价值   实施并在将来避免它们。   如果存在其他任何内容,则它们是错误,我们要求您提交报告。   见下文L.

     

= head2 Bounds Checking Constructs

     

已经使用边界修复了一些错误,包括分段错误   检查构造(在Perl 5.22中引入)C< \ b {gcb}>,C< \ b {sb}>,C< \ b {wb}>,   C< \ B {gcb}>,C< \ B {sb}>和C< \ B {wb}>。所有C< \ B {}>现在匹配空   串;没有C< \ b {}>那些。   L< [perl#126319] | https://rt.perl.org/Ticket/Display.html?id=126319>

此外,记录新边界的 perlrebackslash 并未提及它们在v5.22.0中不起作用。

由于 perldelta 中的不协调以及之前我在perl源中测试的新功能不够充分(甚至根本没有),我忽略了可能的修复。我过早地切断了调查线,本可以节省几个小时。我最近没有让代码在最新的二进制文件上运行,这当然是我的错,但我已经开始关注我做错了什么以及我的代码是问题的想法。尽管我过去经历了许多相反的经历,但我并没有想到 perl 错误的想法(除了更新UCD之外)。

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

答案 1 :(得分:1)

我主要责怪这种情况,但还有其他人参与,所以我会在下面的地方使用复数第一人。

首先,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提供的测试都通过了。它们是短期投入,背景破坏无关紧要。当这一切都得到解决后,我很惊喜地发现\ b {sb}给出的结果更符合人类的期望。

计划在下一版本的UAX#29中修复Unicode错误,我认为我们做出了正确的决定,使得\ b {wb}和\ b {sb}在5.22.1中工作。