欢迎光临散文网 会员登陆 & 注册

开源阅读替换教程&正则替换五步走(中)

2022-09-03 15:45 作者:本雁霜晨月  | 我要投稿


四、限制——限制生效范围

1.首尾:

      “^”匹配字符串的开始位置,“$”匹配结束位置,如^ab$匹配a开头b结尾的字符串,ab则不要求a是开头和b是结尾,注意^和$本身不匹配内容。


2.断言:

       断言也是匹配位置而非内容,断言其实就是判断前后文是否符合条件,只有符合条件才能进行匹配。分别有前向否定(?<!)、前向肯定(?<=)、后向否定(?!)、后向肯定(?=)这四种情况。

      例如示例②和③里面的“(?<=[   \s])”表示只有前面是空格符才能进行匹配,常用于判断首行缩进的段落开头,不匹配空格符。还有示例⑤中的“(?<=[梅荷])”表示判断前面必须是“梅”或“荷”,但不匹配“梅”与“荷”;“(?=[朵枝])”表示后面必须是“朵”或“枝”;“(?![a-z])”表示后面不能是小写字母。

       断言的使用频率极高,它是提高匹配精度和减少错误匹配的最常用方式。追加原文到正则中虽然也能提高匹配精度,但也减小了适用范围,并且也无法做到像断言一样只判断前后内容而不匹配该内容。


3.分组:

       早在数学中我们就学过括号()可以将算式进行分组,表示括号内是一个整体,在正则里面同样有如此效果。正则里的括号()不匹配括号本身,匹配本身需要反斜线\转义。

       在写正则的过程中,如果前面的正则匹配到了一段原文,后面要想匹配一段相同的原文该怎么办呢?我们前面所学正则的匹配思路,无一不是按照原文内容的形式和位置来思考的,而现在要求在匹配到一段原文的基础上再匹配一段与之相同原文,这涉及对内容本身进行匹配,显然超出了之前所学的范畴。此时分组就发挥了作用。

      例如前文提到的原文出现多处重复的情况,我们想匹配重复的内容。

原文:

    “斗之力,三段!”

    “斗之力,三段!”

    天地不仁,以万物为刍狗!

    天地不仁,以万物为刍狗!

替换规则:([^\n]+)\s*\n\s*\1

      规则中“[^\n]+”匹配了任意一个自然段的内容,“\s*\n\s*”匹配了段前段尾出现的空格和换行,“\1”则是对第一个括号匹配的原文内容进行引用,即与前面“.*”匹配到的内容相同。这样我们就能匹配到所有重复的自然段。此外,“[^\n]+”也可写成“.+”,但“+”不可换成“*”。

     在匹配到重复段落之后,我们自然需要去掉多余段落,因为有“\1”这种引用原文的效果,“替换为”的内容也就不难写了。但“替换为”里面用“$1”而非“\1”,这也是引用第一个括号匹配到的原文。

替换规则:([^\n]+)\s*\n\s*\1

替换为:$1

      通过上述分析,以上规则将把所有连续出现两次的重复段落只保留第一个。另外还有\2、\3、\4……以及$2、$3、$4……引用与之相同的相应括号匹配到的原文。

      由此获得启发,段落内的异常换行也有了解决方案。这种异常换行主要表现为在非结尾标点处换行,也就是在不是句号、问号、感叹号、反引号等位置换行,或者说在无标点、逗号、分号、正引号、破折号、顿号、波浪号等位置换行。

替换规则:([^。\.!!"”??\s])\s*\n\s*(.*)

替换为:$1$2


开源阅读替换教程&正则替换五步走(中)的评论 (共 条)

分享到微博请遵守国家法律