查看原文
其他

如何基于SRX将英文文本切分成句(一)

韩林涛 简言 2022-07-09

在之前的帖子中我们介绍过读懂翻译记忆库文件(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的数组知识、循环知识,我们就能够实现断句。


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



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存