如何基于SRX将英文文本切分成句(一)
在之前的帖子中我们介绍过读懂翻译记忆库文件(TMX)所需的XML和DTD基础知识和使用Tmxmall的文档解析API来进行多种类型文档的断句,以及如何基于TMX来制作翻译记忆库(如何制作一个简易的大会报告双语检索工具)。
同样是基于XML技术的SRX却一直没有介绍过,其全称是“Segmentation Rules eXchange”,可译为“断句规则交换”。
简单来说就是:开发计算机辅助翻译工具的厂商约定都按照SRX标准来存储和读取文本断句规则,这些断句规则存储在“.srx”格式的文件中。
有了断句规则,我们就可以轻松的将一篇文章切分成一个个的句段(Segment),而计算机辅助翻译工具最喜欢的就是这种类型的待译原文呈现形式。
写这篇文章的目的就是为大家介绍如何基于SRX将英文文本切分成一个个的句子。
一、“.srx”格式的文件长啥样?
请看下面这个示例:
<?xml version="1.0"?>
<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>元素、<beforebreak>元素和<afterbreak>元素。它们以这样的形式一同出现:
<rule break="yes">
<beforebreak>[\.\?!]+</beforebreak>
<afterbreak>\s</afterbreak>
</rule>
在上面的XML代码中,一个<rule>元素中包含了一条断句规则,这个断句规则分为两部分,首先用<beforebreak>元素定义了“断点”前是什么,然后用<afterbreak>元素定义了“断点”后是什么。
大家需要特别注意“断点”这个概念,以下面这两个句子为例:
Good morning! Welcome to BLCU.
如果我们希望将这段话切分成两句话,我们肯定会选择将其分为“Good morning! ”和“Welcome to BLCU.”
所有要从惊叹号后面进行断句:
Good morning! | Welcome to BLCU.
上面红色的位置就是所谓的“断点”,对应的英文即“Break”。如果我们想让计算机来断句,那么就得告诉计算机断点前是什么,断点后是什么。在上面的例子中,断点前是个惊叹号,断点后是一个空格。
如果我们想用正则表达式来表示惊叹号,直接写“!”就可以。但除了惊叹号之外,我们也可以用问号“?”、句号“.”,而且有时一个句子后面会有好多种情况,比如:
Hi!
What?!
Yes!
Thanks.
No!!!
所以我们用这样一个正则表达式就可以覆盖以上几种情况:[\.\?!]+
\. 表示的是 .
\? 表示的是 ?
! 表示的是 !
[] 表示的是 集合
+ 表示的是 前面的表达式出现一次或多次
正是[]+ 这个正则表达式组合使得我们可以匹配多个符号同时出现的情况。
运行效果如下图:
至于空格,则可以使用正则表达式“\s”来表示。
最后需要再看的就是<rule>元素的“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的数组知识、循环知识,我们就能够实现断句。
在后面的帖子中我们继续为大家介绍。