FME中,如何更优雅的使用正则表达式?

2019-07-31 16:31:18 浏览数 (1)

前言

本次推送来源于FME爱好者凡江林,在征得作者同意后转载。

原作者:凡江林


课题背景

正则表达式是文本字符串处理的瑞士军刀。在FME中,常用来处理文本字符串的转换器主要为:StringSearcher 、StringReplacer。如图(1)所示,其中,StringSearcher用来从指定字段中匹配给定规则的字符串;StringReplacer用来把指定字段中给定规则的字符串替换为给定文本。在使用过程中,两者侧重点不同,但都提供对正则表达式的支持。但从接触FME2016后,发现FME中StringSearcher和StringReplacer对正则表达式的中文匹配不太友好。

图(1)

(1)问题描述

在FME2016中,以StringSearcher为例。StringSearcher提供了正则表达式编辑器,能够预览给定正则表达式的匹配情况。如图(2)所示,为匹配两个连着的数字的正则表达式编辑器窗口。通过窗口,可以很直观的展示正则表达式的匹配情况。

图(2)

但是,如果匹配中文呢。如图(3)所示。我们发现,正则匹配并没有得到正确的匹配结果。

图(3)

有一种方式是把正则表达式,换成汉字对应的Unicode编码。但是,在FME2016中,对以上的市、区换成对应的Unicode编码,匹配依然失效。

(2)流程思路

于是,想到借助FME中可以调用的脚本语言,利用脚本语言的正则表达式特性。FME中比较常用的脚本语言有:TclCaller、PythonCaller、JavaScriptCaller。之前使用过Python2,在Python2中,文本字符串的处理,经常需要在encode和decode之间来回切换。一段时间没有使用,又得重新去温故一遍。

前段时间,在学习JavaScript的过程中,发现了JavaScript中对字符串的编码默认是UTF-16的形式。而当正则表达式添加u修饰符后,它就从编码单元匹配模式切换为字符模式匹配,同时可以对由两个编码单元(4个字节)组成的字符进行正确的匹配。当然,常用的汉字对应一个编码单元(16位,两个字节)。在JavaScriptCaller中使用正则表达式,是不需要考虑汉字的Unicode编码的,把一个汉字当做一个字符一样的操作匹配就可以。如图(4)所示,为在JavaScriptCaller中匹配字符串(“这是一段汉语文本。这是日期20180623;这是浮点数2333.222这是另一段文本。贵州省贵阳市XX区”)的样本流程。

图(4)

如图(5)所示,对应的结果正确的匹配相应的字符串。从图(4)和图(5)可知,相对于FME提供的正则表达式的原生支持,JavaScript中,对于正则表达式的支持更优雅。

图(5)

(3)探索结论

通过以上的分析我们了解到,在FME中利用JavaScriptCaller来使用正则表达式可以更优雅。事实上,如果对于正则表达式比较了解。比如,读过《精通正则表达式》(第三版),等。就会发现,Perl语言最重要的特性就是它内部集成了正则表达式引擎;而JavaScript语言集成了Perl对应的正则引擎。由此可见,JavaScript对于正则表达式的支持,同Perl一样的强悍。

同时,前面介绍过,JavaScript字符串一直基于16位字符编码,这就给汉字与英文字母及其他字符,提供了一个通用正则表达式匹配的标准。从而,在FME中,我们可以通过JavaScriptCaller的正则表达式引擎,匹配汉字同匹配数字以及其他英文字符一样,不需要去查询对应的Unicode编码。同时,也让思维更加专注于正则表达式匹配模式本身。

(限于作者的学识和经验,定有不少疏漏和不当之处,甚至是错误也在所难免,恳请读者和同行批准指正!)


结语

在之前的推送中,曾经写到过如何在FME中使用正则表达式。本文作者从另一个角度写了如何在FME中使用正则,就如之前所说FME是一个开放的平台,可以容纳很多,不管你是喜欢使用Py还是JS,都可以以自己擅长的方式扩展它的功能。

0 人点赞