跳转至

给编辑朋友的正则表达式课程

最近的更新在末尾

很多编辑只会用Word。有些编辑也会用WPS,但他以为自己是在用Word;如果给他装Libreoffice Writer,他会稍稍不适应,但很快也能用起来。

如果一个编辑希望稍微进一步学点“电脑知识”,我推荐学正则表达式。再搭配使用高效的文本处理工具,比如

  • TextPro(除非特别说明,文中例子都是TextPro环境中的),
  • EmEditor,
  • VSCode,
  • PowerGrep,
  • Libreoffice Writer,

以及一些文档管理工具,比如

  • Total Commander,
  • Everything,

那你就可以说是编辑界的极客了。

据说中华书局的很多青年编辑都会正则表达式,并自称为正则青年。其实每个人都能学会。

跟很多编辑同事、朋友讲过这个意思(最近还许诺开一个在线的Python入门课),说要给他们讲课,一直没有实行。这个帖子就是为讲课预备的,积累一些实际用例。

会不断更新。也可能很久不更新。

“正则表达式”什么意思?#

正则表达式(regular expression)就是规则表达式,可以用来表示多个符合此规则的字符串。比如\d\d\d表示连续的3个数字,如125、121、254等等。

他可以用来查找文本中符合规则的所有字符串,还可以按一定的规则进行替换;也可以用来查找文件名符合规则的所有文件,还可以按一定规则更改文件名、移动位置;等等。

正则表达式只是一种约定,在不同软件、编程语言中的语法规则、使用方式、功能是不同的。所有,学正则表达式一般是配合某些软件、编程语言来学习。文字工作者可以配合引言中讲到的软件来学习、使用。

学正则该从哪里下手#

使用汉字的文字工作者,最好从TextPro开始。TextPro是中华佛典宝库网站开发的,是用来整理佛经的文本处理工具。它的正则,对汉字有专门的设计,比如有专门的字符集可以方便地区分汉字和汉字中的标点、数字、大写数字、天干地支用字、拼音用字符、注音符号,等等;它还能处理批量正则替换表(一般的软件都没有这一功能,或者没它方便);还带有一个专门的正则帮助文件,清晰,简明,有示例,相当于一个教程,用它学习入门就可以。

查找AABB式的词语#

【查找】(\c)\1(\c)\2

\c代表一个汉字。()代表捕获其间的内容,以备引用,\1即是引用第一个捕获;那么(\c)\1就表示两个重复的汉字。

如果你想把这些词语(或所在行)收集到一个文件中,TextPro的“编辑”菜单中有两个现成的功能:“复制所有查找结果”和“复制所有查找结果”。

删除重复行#

可以用正则处理(参见下面的思路),但一般使用软件现成的功能。EmEditor、TextPro,甚至excel都有这样的功能。

可以像Excel那样,某一列相同的很多行,只保留一行吗?#

用EmEditor跨行正则替换。先按行排序,把有相同值的行都排到一起,然后

【查找】^((.*?)\t.*)\n\2\t.*$
【替换】\1

其实,EmEditor中现成有这个功能:编辑.高级.删除/把重复行作为书签

正则表达式如何排除汉字?#

【答】

正则表达式有很多方言,光说“正则表达式”是不清楚的。

一般可以用反字符集的形式,类似[^\u4E00-\u9FA5],表示Unicode编码段\u4E00-\u9FA5(包含两万多汉字)之外的字符。汉字有好几个Unicode编码段,这里只是比较常用的一段;如果有必要,还要加入其他的编码段。

如果是用编辑器处理,建议用textPro,中文字符、中文标点、大写数字、拼音,等等,都做成通配符。比如\c匹配汉字,\~c匹配汉字之外的全角字符。

匹配a_string,但不匹配b_string的正则写法#

如要匹配no good xxxingno use xxxing, 但不匹配no longer xxxing。 正则类似这样:no (?!longer) [^\s]*ing,但不对。要怎么写?

【答】

no (?!longer)\w+ \w+ing

其中,(?!longer)表示匹配此处没有longer的情况。\w表示可构词的字符,包括数字和下划线。

跨行处理#

有些工具可以跨行使用正则查找、替换,比如EmEditor、vscode、Libreoffice Writer(要安装插件altsearch)。 不能跨行处理的软件,可以把所有行合并成一行后再处理。——用一些文本中不可能有的符号组合标记分行的位置,比如@@@@,处理完后还可能恢复分行。

部分内容跨行移动#

有很多如下的试题,需要把答案从最后一行末尾,移动到对应序号行的末尾。

3.在什么情况下不得行车?
A、车窗没关闭
B、车门没关闭
C、音响没关闭
D、顶窗没关闭    答案:B

改为:

3.在什么情况下不得行车?
A、车窗没关闭
B、车门没关闭    答案:B
C、音响没关闭
D、顶窗没关闭

EmEditor虽能跨行查找,但跨行反向用好像有问题。那么先用@@@@代替换行符,然后分段移动,最后再恢复分行。

以下是批处理替换的设置:

以下是导出的tsv文件内容。有tab分割的四栏分别对应启用 | 查找| 替换为 | 条件,可以后缀.tsv保存为文件,再导入EmEditor使用。

on  \n  @@@@    RD
on  @@@@([A-C])([^\s]+?)(@@@@[^\s]+?)(\s+答案:\1) @@@@\1\2\4\3    RD
on  @@@@    \n  RD

怎么用EmEditor把中间一段移到句首#

如把可|不|能转换成不|可|能

【答】

【查找】^(.+)\|(.+)\|(.+)$
【替换】\2|\1|\3

此类比较规则的文本,也可以用EmEditor的csv表格操作功能,可以直接移动整列。