3

Moses Tokenizer是机器翻译和自然语言处理实验中广泛使用的分词器。

有一行正则表达式检查:

if (($pre =~ /\./ && $pre =~ /\p{IsAlpha}/) || 
   ($NONBREAKING_PREFIX{$pre} && $NONBREAKING_PREFIX{$pre}==1) || 
   ($i<scalar(@words)-1 && ($words[$i+1] =~ /^[\p{IsLower}]/)))

如果我错了请纠正我,第二和第三个条件是检查

  • 前缀是否在不间断前缀列表中
  • 该单词是否不是最后一个标记,并且仍然有一个小写标记作为下一个单词。

问题在于它检查的第一个条件:

($pre =~ /\./ && $pre =~ /\p{IsAlpha}/)
  1. 检查前缀是否是$pre =~ /\./单个句号?

  2. 并且正在$pre =~ /\p{IsAlpha}/检查前缀是否是perluniprop中字母列表中的字母?

  3. 一个相关的问题是句号是否已经在 perluniprop 字母表中?如果是这样,这个条件不是永远不会成立吗?

4

1 回答 1

3

如果我错了[关于$NONBREAKING_PREFIX{$pre} && $NONBREAKING_PREFIX{$pre}==1检查]前缀是否在不间断前缀列表中,请纠正我

在不知道%NONBREAKING_PREFIX包含什么的情况下无法判断,但这是一个公平的猜测。

如果我错了[关于$i<scalar(@words)-1 && ($words[$i+1] =~ /^[\p{IsLower}]/)检查]该单词是否不是最后一个标记并且仍然有一个小写标记作为下一个单词,请纠正我

假设代码正在迭代@words,并且$i是当前单词的索引,那么它会检查当前单词后面是否跟着一个以小写字母开头的单词(由 Unicode 定义)。

检查前缀是否是$pre =~ /\./单个句号?

不完全的。它检查字符串中的任何$pre字符是否是句号。

$ perl -e'CORE::say "abc.def" =~ /\./ ? "match" : "no match"'
match

$ perl -e'CORE::say "abc!def" =~ /\./ ? "match" : "no match"'
no match

Perl 首先尝试在位置 0 找到匹配项,然后在位置 1 处,依此类推,直到找到匹配项。

并且 $pre =~ /\p{IsAlpha}/ 检查前缀是否是 perluniprop 中字母列表中的 alpha?

\p{IsAlpha}确实在perluniprops中定义。[注意正确的拼写。] 它定义

\p{Is_*}          ⇒   \p{*}
\p{Alpha}         ⇒   \p{XPosixAlpha}
\p{XPosixAlpha}   ⇒   \p{Alphabetic=Y}

\p{Alpha: *}      ⇒   \p{Alphabetic=*}
\p{Alphabetic}    ⇒   \p{Alphabetic=Y}

[1]\p{IsAlpha}的别名也是如此。Unicode 定义了哪些字符是 Alphabetic [2]。有不少:\p{Alphabetic=Y}

$ unichars '\p{Alpha}' | wc -l
10391

所以回到这个问题。$pre =~ /\p{IsAlpha}/检查字符串 in 中的任何$pre字符是否是字母字符。

一个相关的问题是句号是否已经在 perluniprop 字母表中?

不。

$ perl -e'CORE::say "." =~ /\p{IsAlpha}/ ? "match" : "no match"'
no match

$ uniprops .
U+002E <.> \N{FULL STOP}
    \pP \p{Po}
    All Any ASCII Assigned Basic_Latin Punct Is_Punctuation Case_Ignorable CI Common Zyyy Po P
       Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Other_Punctuation Pat_Syn Pattern_Syntax
       PatSyn POSIX_Graph POSIX_Print POSIX_Punct Print X_POSIX_Print Punctuation STerm Term
       Terminal_Punctuation Unicode X_POSIX_Punct

相比之下,

$ uniprops a
U+0061 <a> \N{LATIN SMALL LETTER A}
    \w \pL \p{LC} \p{L_} \p{L&} \p{Ll}
    AHex POSIX_XDigit All Alnum X_POSIX_Alnum Alpha X_POSIX_Alpha Alphabetic Any ASCII
       ASCII_Hex_Digit Assigned Basic_Latin ID_Continue Is_IDC Cased Cased_Letter LC
       Changes_When_Casemapped CWCM Changes_When_Titlecased CWT Changes_When_Uppercased CWU Ll L
       Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Hex X_POSIX_XDigit Hex_Digit IDC ID_Start
       IDS Letter L_ Latin Latn Lowercase_Letter Lower X_POSIX_Lower Lowercase PerlWord POSIX_Word
       POSIX_Alnum POSIX_Alpha POSIX_Graph POSIX_Lower POSIX_Print Print X_POSIX_Print Unicode Word
       X_POSIX_Word XDigit XID_Continue XIDC XID_Start XIDS

如果是这样,这个条件不是永远不会成立吗?

$ perl -E'CORE::say /\./ && /\p{IsAlpha}/ ? "match" : "no match" for $ARGV[0]' a
no match

$ perl -E'CORE::say /\./ && /\p{IsAlpha}/ ? "match" : "no match" for $ARGV[0]' .
no match

$ perl -E'CORE::say /\./ && /\p{IsAlpha}/ ? "match" : "no match" for $ARGV[0]' a.
match

  1. 下划线和空格被忽略,所以\p{IsAlpha}\p{Is_Alpha}都是\p{I s_A l p_h_a}等价的。

  2. 字母字符列表与字母字符列表略有不同。

    $ unichars '\p{Letter}' | wc -l
    9540
    
    $ unichars '\p{Alpha}' | wc -l
    10391
    

    所有字母都是字母,但一些字母标记、罗马数字等也是如此。

于 2017-02-14T16:50:45.427 回答