韩林涛老师:译者编程知识30天×300字写作计划 | Day 15

在之前的帖子中我们介绍过读懂翻译记忆库文件(TMX)所需的 XMLDTD 基础知识和使用 Tmxmall 的文档解析 API 来进行多种类型文档的断句,以及如何基于 TMX 来制作翻译记忆库(如何制作一个简易的大会报告双语检索工具)。

同样是基于 XML 技术的 SRX 却一直没有介绍过,其全称是“Segmentation Rules eXchange”,可译为“断句规则交换”。

简单来说就是:开发计算机辅助翻译工具的厂商约定都按照 SRX 标准来存储和读取文本断句规则,这些断句规则存储在“.srx”格式的文件中。

有了断句规则,我们就可以轻松的将一篇文章切分成一个个的句段(Segment),而计算机辅助翻译工具最喜欢的就是这种类型的待译原文呈现形式。

写这篇文章的目的就是为大家介绍如何基于 SRX 将英文文本切分成一个个的句子。

一、“.srx”格式的文件长啥样?

请看下面这个示例:

<srx version="2.0" 
  xmlns="http://www.lisa.org/srx20"
  xsi:schemaLocation="http://www.lisa.org/srx20 srx20.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <header segmentsubflows="yes" cascade="yes">
        <formathandle type="start" include="no"/>
        <formathandle type="end" include="yes"/>
        <formathandle type="isolated" include="yes"/>
    </header>
    <body>
        <languagerules>
            <languagerule languagerulename="Default">
                <!-- Common rules for most languages -->
                <rule break="no">
                    <beforebreak>^\s*[0-9]+\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
                <rule break="yes">
                    <afterbreak>\n</afterbreak>
                </rule>
                <rule break="yes">
                    <beforebreak>[\.\?!]+</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
            </languagerule>
            <languagerule languagerulename="English">
                <!-- Some English abbreviations -->
                <rule break="no">
                    <beforebreak>\s[Ee][Tt][Cc]\.</beforebreak>
                    <afterbreak>\s[a-z]</afterbreak>
                </rule>
                <rule break="no">
                    <beforebreak>\sMr\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
                <rule break="no">
                    <beforebreak>\sU\.K\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
            </languagerule>
            <languagerule languagerulename="French">
                <!-- Some French abbreviations -->
                <rule break="no">
                    <beforebreak>\s[Mm]lle\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
                <rule break="no">
                    <beforebreak>\s[Mm]lles\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
                <rule break="no">
                    <beforebreak>\s[Mm]me\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
                <rule break="no">
                    <beforebreak>\s[Mm]mes\.</beforebreak>
                    <afterbreak>\s</afterbreak>
                </rule>
            </languagerule>
            <languagerule languagerulename="Japanese">
                <!-- Rules for breaking on Japanese punctuation
                
                \xff61: Halfwidth ideographic full stop
                \x3002: Ideographic full stop
                \xff0e: Fullwidth full stop
                \xff1f: Fullwidth question mark
                \xff01: Fullwidth exclamation mark
                -->
                <rule break="yes">
                    <beforebreak>[\xff61\x3002\xff0e\xff1f\xff01]+</beforebreak>
                    <afterbreak></afterbreak>
                </rule>
            </languagerule>
        </languagerules>
        <maprules>
            <!-- List exceptions first -->
            <languagemap languagepattern="[Ee][Nn].*" languagerulename="English"/>
            <languagemap languagepattern="[Ff][Rr].*" languagerulename="French"/>
            <!-- Japanese breaking rules -->
            <languagemap languagepattern="[Jj][Aa].*" languagerulename="Japanese"/>
            <!-- Common breaking rules -->
            <languagemap languagepattern=".*" languagerulename="Default"/>
        </maprules>
    </body>
</srx>

来源:https://www.gala-global.org/srx-20-april-7-2008

如果你之前看过我录制的 XML 基础视频,看到这个样子的文件肯定就不陌生了,如果你没有看过而且不知道什么是 XML,那么就可以关掉这个页面,先去看这篇帖子:读懂翻译记忆库文件(TMX)所需的 XML 和 DTD 基础知识。

二、SRX 文件是如何存储断句规则的?

要想知道 SRX 文件是如何存储断句规则的,除了需要有 XML 基础知识外,更重要的是要掌握正则表达式的基础,我也同样录过一系列的视频:面向文科生的正则表达式基础视频教程。很抱歉,你可能又要关掉这个页面,去补一下正则表达式的基础知识了。

在 SRX 文件中,你会看到三个非常重要的元素:元素、元素和元素。它们以这样的形式一同出现:

<rule break="yes">
    <beforebreak>[\.\?!]+</beforebreak>
    <afterbreak>\s</afterbreak>
</rule>

在上面的 XML 代码中,一个元素中包含了一条断句规则,这个断句规则分为两部分,首先用元素定义了“断点”前是什么,然后用元素定义了“断点”后是什么。

大家需要特别注意“断点”这个概念,以下面这两个句子为例:

Good morning! Welcome to BLCU.

如果我们希望将这段话切分成两句话,我们肯定会选择将其分为“Good morning! ”和“Welcome to BLCU.”

所有要从惊叹号后面进行断句:

Good morning! | Welcome to BLCU.

上面红色的位置就是所谓的“断点”,对应的英文即“Break”。如果我们想让计算机来断句,那么就得告诉计算机断点前是什么,断点后是什么。在上面的例子中,断点前是个惊叹号,断点后是一个空格。

如果我们想用正则表达式来表示惊叹号,直接写“!”就可以。但除了惊叹号之外,我们也可以用问号“?”、句号“.”,而且有时一个句子后面会有好多种情况,比如:

Hi! What?! Yes! Thanks. No!!!

所以我们用这样一个正则表达式就可以覆盖以上几种情况:[.?!]+

. 表示的是 . ? 表示的是 ? ! 表示的是 ! [] 表示的是 集合

  • 表示的是 前面的表达式出现一次或多次

正是[]+ 这个正则表达式组合使得我们可以匹配多个符号同时出现的情况。

运行效果如下图:

至于空格,则可以使用正则表达式“\s”来表示。

最后需要再看的就是元素的“break”属性值,如果这个值是“yes”就表明要在这个断点将句子断开,如果是“no”就表明不断开。

了解上面这个断句规则的实现原理后,再来看这两段 XML 代码你就更了解断句规则是如何存储的了:

<rule break="yes">
    <beforebreak>[\.\?!]+</beforebreak>
    <afterbreak>\s</afterbreak>
</rule>
<rule break="no">
    <beforebreak>\sMr\.</beforebreak>
    <afterbreak>\s</afterbreak>
</rule>

最初提出 SRX 标准的本地化专家们考虑到了非常多的断句规则,涉及不同的断句场景,涉及不同的语言,涉及断句规则如何扩充,涉及断句规则如何应用。SRX 标准早在2004年便正式使用,现在通行的是2008年的第二个版本,发起者均是本地化行业标准协会(LISA, Localization Industry Stardards Association)。LISA 推动了本地化行业非常重要的几个标准:TMX、TBX、SRX。但在2011年2月,该组织因资不抵债而关闭。如今全球化与本地化协会(GALA, Globalization and Localization Association)的官网上还可以看到这些标准的全文,这也是我们了解本地化行业标准的主要渠道。

三、如何通过代码来实现断句?

如果我们想用代码来实现断句,自然需要先知道原理。我们在这一系列文章中将依然以PHP作为实现断句的编程语言。

因为 SRX 中断句实现的主要路径是正则表达式,所以我们会介绍 PHP 中与正则表达式操作相关的函数:preg_replace()、preg_match()、preg_match_all()、explode()。

因为 SRX 是基于 XML 的,所以我会带着大家回顾之前的帖子中讲过的 XML 读取函数simplexml_load_file()。

配合 PHP 的数组知识、循环知识,我们就能够实现断句。

在后面的帖子中我们继续为大家介绍。

本文原文《如何基于SRX将英文文本切分成句(一)》发表于韩老师的公众号《简言》。

作者:韩林涛,北京语言大学高级翻译学院教师,《译者编程入门指南》作者