在JavaScript中实现SRX分段规则

时间:2010-05-03 15:02:19

标签: javascript regex localization

我想使用javascript从文本中提取句子来实现SRX分段规则。

为了正确执行此操作,我必须遵循SRX规则。

例如。 http://www.lisa.org/fileadmin/standards/srx20.html#refTR29

现在有两种类型的正则表达式

  1. 如果发现句子应该像“。”那样打破。
  2. 如果发现的句子不应该像缩写U.K或Mr.
  3. 那样破坏

    为此再次有两个部分

    1. 在破坏之前
    2. 打破后
    3. 例如,如果规则是

      <rule break="no">
      
          <beforebreak>\s*[0-9]+\.</beforebreak>
          <afterbreak>\s</afterbreak>
      
      </rule>
      

      其中说如果找到“\ s * [0-9] +。\ s”模式,则该段不应该中断。

      如何使用javascript实现,我的分割功能还不够?

1 个答案:

答案 0 :(得分:4)

你可能想尝试这样的事情:

function segment(text, rules) {
    if (!text) return text;
    if (!rules) return [text];

    var rulePattern = /<rule(?:(\s+break="no")|\s+[^>]+|\s*)>(?:<beforebreak>([^<]+)<\/beforebreak>)?(?:<afterbreak>([^<]+)<\/afterbreak>)?<\/rule>/g;
    cleanXml(rules).replace(rulePattern, 
        function(whole, nobreak, before, after) {
            var r = new RegExp((before||'')+'(?![\uE000\uE001])'+(after?'(?='+after+')':''), 'mg');
            text = text.replace(r, nobreak ? '$&\uE000' : '$&\uE001');
            return '';
        }
    );

    var sentences = text.replace(/\uE000/g, '').split(/\uE001/g);

    return sentences;
}

function cleanXml(s) {
    return s && s.replace(/<!--[\s\S]*?-->/g,'').replace(/>\s+</g,'><');
}

要运行此操作,只需使用要拆分的文本调用segment(),并将规则XML作为字符串。例如:

segment('The U.K. Prime Minister, Mr. Blair, was seen out with his family today.',
        '<rule break="no">' +
            '<beforebreak>\sMr\.</beforebreak>' +
            '<afterbreak>\s</afterbreak>' +
        '</rule>' +
        '<rule break="no">' +
            '<beforebreak>\sU\.K\.</beforebreak>' +
            '<afterbreak>\s</afterbreak>' +
        '</rule>' +
        '<rule break="yes">' +
            '<beforebreak>[\.\?!]+</beforebreak>' +
            '<afterbreak>\s</afterbreak>' +
        '</rule>'
);

segment()的调用将返回一系列句子,因此您只需执行alert(segment(...).join('\n'))之类的操作即可查看结果。

已知限制:

  1. 它希望规则在cascading process之后,与特定语言相关。
  2. 它希望规则使用的正则表达式符合javascript regexp语法。
  3. 它不处理内部标记。
  4. 所有这些限制似乎都很容易克服。

    这是如何工作的?

    段函数使用rulePattern提取每个规则,确定它是违反规则还是非破坏规则,并根据规则的beforebreak和afterbreak子句创建regexp。然后它扫描文本,并通过添加unicode字符(取自unicode私有使用区域)标记每个匹配位置,该字符标记是中断(\ uE001)还是非中断(\ uE000)。如果另一个标记已经位于同一位置,则规则不匹配,以保留规则优先级。

    然后它只是删除非断裂标记,并根据断裂标记分割文本。

    @Sourabh:我希望这对你仍然有用。