扫码阅读
手机扫码阅读

文本处理神器是什么?

13 2024-12-24

我们非常重视原创文章,为尊重知识产权并避免潜在的版权问题,我们在此提供文章的摘要供您初步了解。如果您想要查阅更为详尽的内容,访问作者的公众号页面获取完整文章。

查看原文:文本处理神器是什么?
文章来源:
数据治理体系
扫码关注公众号

一、前言


花了一整天时间 ,系统性学了一遍正则表达式,相当不错,分享给大家,大家可以收藏备忘,需要的时候找出来查询使用就行。

个人体会,正则表达式不难,使用的时候在网上找找案例就行,但是如果你对他有全局了解,你就会发现,在未来使用和查找都会达到事半功倍的效果。


正则表达式是什么,有什么用


正则表达式(Regular Expression),简称 RE。在编程语言中,正则常常用来简化文本处理的逻辑。正则是一个非常强大的文本处理工具,它的应用极其广泛。我们可以利用它来校验数据的有效性,比如用户输入的手机号和邮箱是不是符合规则;也可以从文本中提取想要的内容,比如从网页中抽取数据;还可以用来做文本内容替换和切割,从而得到我们想要的内容。

 

三、正则表达式的构成


正则表达式主要由元字符构成, \d,它在正则中不代表 \ (反斜杠) 加字母 d,而是代表任意数字,这种表示特殊含义的字符表示,就是元字符。正则表达式中,元字符非常多,我们可以把元字符大致分成5类,分别是表示单个特殊字符的,表示空白符的,表示次数的量词,表示某个范围的,另外还有表示断言的.


1. 特殊单字符:

英文的点(.表示换行以外的任意单个字符,

\d 表示任意单个数字,

\w 表示任意单个数字或字母或下划线,

\s 表示任意单个空白符。

另外,还有与之对应的三个 \D、\W \S,分别表示着和原来相反的意思。


2. 空白符:大部分场景使用 \s 就可以满足需求,\s 代表任意单个空白符号。

\r回车符

\n 换行符

\f 换页符

\t 制表符

\v垂直制表符


3. 量词:

英文的星号(* 0 到多次

加号(+ 1 到多次,

问号(? 0 1 次,

?:01次、

{m}:出现m

{m,}:出现至少m

{m,n} m n 次。

 

4. 范围:在正则表达式中,表示范围的符号有四个分类。

管道符号,我们用它来隔开多个正则,表示满足其中任意一个就行,比如 ab|bc 能匹配上 ab,也能匹配上 bc,在正则有多种情况时,这个非常有用。

中括号[]代表多选一,可以表示里面的任意单个字符,所以任意元音字母可以用 [aeiou] 来表示。另外,中括号中,我们还可以用中划线表示范围,

[a-z] 可以表示所有小写字母。

脱字符(^,表示非,不能是里面的任何单个元素。


5.断言:^ $ 符号

 

四、正则表达式的三种模式


正则中的三种模式,贪婪匹配、非贪婪匹配和独占模式。

贪婪模式Greedy):简单说就是尽可能进行最长匹配。表示次数的量词默认是贪婪的,在贪婪模式下,会尝试尽可能最大长度去匹配。

非贪婪模式Lazy):尽可能进行最短匹配。

我们可以在量词后面加上英文的问号 (?),将贪婪模式变成非贪婪模式呢?。

独占模式(Possessive

不管是贪婪模式,还是非贪婪模式,都需要发生回溯才能完成相应的功能。独占模式,它类似贪婪匹配,但匹配过程不会发生回溯,因此在一些场合下性能会更好。

独占模式和贪婪模式很像,独占模式会尽可能多地去匹配,如果匹配失败就结束,不会进行回溯,这样的话就比较节省时间。具体的方法就是在量词后面加上加号(+)。需要注意的是 Python Go 的标准库目前都不支持独占模式,会报错。

回溯

regex = “xy{1,3}z”

text = “xyyz”

在匹配时,y{1,3}会尽可能长地去匹配,当匹配完 xyy 后,由于 y 要尽可能匹配最长,即三个,但字符串中后面是个 z 就会导致匹配不上,这时候正则就会向前回溯,吐出当前字符 z,接着用正则中的 z 去匹配。

如果我们把这个正则改成非贪婪模式,如下:

regex = “xy{1,3}?z”

text = “xyyz”

由于 y{1,3}? 代表匹配 1 3 y,尽可能少地匹配。匹配上一个 y 之后,也就是在匹配上 text 中的 xy 后,正则会使用 z text 中的 xy 后面的 y 比较,发现正则 z y 不匹配,这时正则就会向前回溯,重新查看 y 匹配两个的情况,匹配上正则中的 xyy,然后再用 z 去匹配 text 中的 z,匹配成功。

 


 

五、正则表达式的分组


分组与编号

括号在正则中可以用于分组,被括号括起来的部分“子表达式”会被保存成一个子组。

那分组和编号的规则是怎样的呢?其实很简单,用一句话来说就是,第几个括号就是第几个分组。

假设时间格式是 2020-05-10 20:23:05 。

日期分组编号是 1,时间分组编号是 5,年月日对应的分组编号分别是 234,时分秒的分组编号分别是 678

下面以Python3 为例,给出一个示例。

>>> import re

>>> test_str = "2020-05-10 20:23:05"

>>> regex = r"((\d{4})-(\d{2})-(\d{2})) ((\d{2}):(\d{2}):(\d{2}))"

>>> subst = r"日期\1 时间\5   \2\3\4\6\7\8"

>>> re.sub(regex, subst, test_str)

'日期2020-05-10 时间20:23:05   20200510202305'

 


 

六、正则中的匹配模式(Match Mode


所谓匹配模式,指的是正则中一些改变元字符匹配行为的方式,比如匹配时不区分英文字母大小写。常见的匹配模式有 4 种,分别是不区分大小写模式、点号通配模式、多行模式和注释模式。

不区分大小写模式,它可以让整个正则或正则中某一部分进行不区分大小写的匹配。

点号通配模式也叫单行匹配,改变的是点号的匹配行为,让其可以匹配任何字符,包括换行。

多行匹配说的是 ^ $ 的匹配行为,让其可以匹配上每行的开头或结尾。

注释模式则可以在正则中添加注释,让正则变得更容易阅读和维护。

不区分大小写模式(Case-Insensitive

不分大小写的英文是 Case-Insensitive,那么对应的模式标识就是 I 的小写字母 i,所以不区分大小写的 cat 就可以写成  (?i)cat

修饰符如果在括号内,作用范围是这个括号内的正则,而不是整个正则;

点号通配模式(Dot All

正则中提供了一种模式,让英文的点(.)可以匹配上包括换行的任何字符。

这个模式就是点号通配模式,有很多地方把它称作单行匹配模式,但这么说容易造成误解,毕竟它与多行匹配模式没有联系,因此在课程中我们统一用更容易理解的“点号通配模式”。

单行的英文表示是 Single Line,单行模式对应的修饰符是 (?s),我还是选择用 the cat 来给你举一个点号通配模式的例子。如下图所示:

需要注意的是,JavaScript 不支持此模式,那么我们就可以使用前面说的[\s\S]等方式替代。在 Ruby 中则是用 Multiline,来表示点号通配模式(单行匹配模式),我猜测设计者的意图是把点(.)号理解成“能匹配多行”。

多行匹配模式(Multiline

通常情况下,^匹配整个字符串的开头,$ 匹配整个字符串的结尾。多行匹配模式改变的就是 ^ $ 的匹配行为。

多行模式的作用在于,使  ^ 和 $ 能匹配上每行的开头或结尾,我们可以使用模式修饰符号 (?m) 来指定这个模式。

这个模式有什么用呢?在处理日志时,如果日志以时间开头,有一些日志打印了堆栈信息,占用了多行,我们就可以使用多行匹配模式,在日志中匹配到以时间开头的每一行日志。

值得一提的是,正则中还有 \A 和 \zPython 中是 \Z) 这两个元字符容易混淆,\A 仅匹配整个字符串的开始,\z 仅匹配整个字符串的结束,在多行匹配模式下,它们的匹配行为不会改变,如果只想匹配整个字符串,而不是匹配每一行,用这个更严谨一些。

注释模式(Comment

正则中注释模式是使用 (?#comment) 来表示。

比如我们可以把单词重复出现一次的正则 (\w+) \1 写成下面这样,这样的话,就算不是很懂正则的人也可以通过注释看懂正则的意思。

(\w+)(?#word) \1(?#word repeat again)

 

 


七、正则表达式断言


什么是断言呢?简单来说,断言是指对匹配到的文本位置有要求。这么说你可能还是没理解,我通过一些例子来给你讲解。你应该知道 \d{11} 能匹配上 11 位数字,但这 11 位数字可能是 18 位身份证号中的一部分。再比如,去查找一个单词,我们要查找 tom,但其它的单词,比如 tomorrow 中也包含了 tom

也就是说,在有些情况下,我们对要匹配的文本的位置也有一定的要求。为了解决这个问题,正则中提供了一些结构,只用于匹配位置,而不是文本内容本身,这种结构就是断言。常见的断言有三种:单词边界、行的开始或结束以及环视。

单词的边界、行的开始或结束、环视。

单词的边界是使用 \b 来表示,这个比较简单。而多行模式下,每一行的开始和结束是使用 ^ $ 符号。如果想匹配整个字符串的开始或结束,可以使用 \A \z,它们不受匹配模式的影响。

最后就是环视,它又分为四种情况:肯定逆向环视、否定逆向环视、肯定顺序环视、否定顺序环视。在使用的时候记住一个方法:有左尖括号代表看左边,没有尖括号是看右边,而感叹号是非的意思。

 

八、正则表达式转义


转义字符(Escape Character)。它在维基百科中是这么解释的:在计算机科学与远程通信中,当转义字符放在字符序列中,它将对它后续的几个字符进行替代并解释。通常,判定某字符是否为转义字符由上下文确定。转义字符即标志着转义序列开始的那个字符。

转义序列通常有两种功能。第一种功能是编码无法用字母表直接表示的特殊数据。第二种功能是用于表示无法直接键盘录入的字符(如回车符)。

如何在正则中正确表示“反斜杠”呢?答案是写四个反斜杠。

 

九、结语


上面是本人对正则表达式的知识梳理,仅供参考和辅助理解,资料来源于网络和自己的总结,如果对你有帮助,烦请星标收藏,关注、转发,如有任何问题,请留言或加我微信入群,我们一起探讨,一起持续构建数据治理体系。

 

 

 

想要了解更多内容?

查看原文:文本处理神器是什么?
文章来源:
数据治理体系
扫码关注公众号

持续完善数据治理实战体系,数据仓库、标签、指标体系,实现业务数字化,数字资产化,资产业务化,资产资本化;回归业务场景的数字化案例才最具参考价值,最容易理解和借鉴的。关注我,和您一起终身学习。

29 篇文章
浏览 445
加入社区微信群
与行业大咖零距离交流学习
SAFe6.0与CMMI3.0映射
白皮书上线