从零开始学Python数据分析与挖掘
上QQ阅读APP看书,第一时间看更新

3.3 字符串处理方法

3.3.1 字符串的常用方法

在平时的工作中,也会碰见字符串型数据的处理,例如如何截取字符串中的某一段内容、如何将字符串按照某个指定的分隔符将其切割开、如何对字符串中的某些值进行替换等。本节内容重点讲述有关字符串的几种常见处理“方法”,首先介绍一下Python中的字符串有哪些构造方法:

构造字符串可以使用三种形式的引号,如果字符串的内容不包含任何引号,那么单引号、双引号和三引号都可以使用;如果字符串的内容仅包含双引号,类似变量string1的形式,那么只能使用单引号或三引号构造字符串;如果字符串的内容仅包含单引号,类似变量string2的形式,那么只能使用双引号或三引号完成字符串的创建;如果字符串的内容既包含单引号,又包含双引号,类似变量string3所示,那只能使用三引号构建字符串。所以,三引号是适用情况最多的字符串构造方法,而且三引号允许长字符串的换行,这是其他两种引号无法实现的,如变量string4所示。

接下来将字符串的常用“方法”汇总到表3-4中,以便读者学习和查阅。

表3-4 字符串的常用方法

为了使读者很好地理解表3-4中的字符串“方法”,下面通过一些小例子作为字符串常用“方法”的解释:

需要说明的是,字符串的index和find方法都是只能返回首次发现子串的位置,如果子串在原字符串中没有找到,对于index方法来说,则返回报错信息,对于find方法,则返回值-1。所以,推荐使用find方法寻找子串的位置,因为即使找不到子串也不会因为错误而影响其他程序的正常执行。

有时,光靠字符串的这些“方法”无法实现字符串的其他处理功能,例如,怎样在字符串中找到有规律的目标值、怎样替换那些不是固定值的目标内容、怎样按照多个分隔符将字符串进行切割等。关于这方面问题的解决,需要用到字符串的正则表达式,接下来我们就进入正则表达式的学习。

3.3.2 正则表达式

正则表达式就是从字符串中发现规律,并通过“抽象”的符号表达出来。打个比方,对于2,5,10,17,26,37这样的数字序列,如何计算第7个值,肯定要先找该序列的规律,然后用n2+1这个表达式来描述其规律,进而得到第7个值为50。对于需要匹配的字符串来说,同样把发现规律作为第一步,本节主要使用正则表达式完成字符串的查询匹配、替换匹配和分割匹配。在进入字符串的匹配之前,先来了解一下都有哪些常用的正则符号,见表3-5。

表3-5 常用的正则符号

如果读者能够比较熟练地掌握表3-5中的内容,相信在字符串处理过程中将会游刃有余。如前文所说,本节将基于正则表达式完成字符串的查询、替换和分割操作,这些操作都需要导入re模块,并使用如下几个函数。

1.匹配查询函数

findall(pattern, string, flags=0)

findall函数可以对指定的字符串进行遍历匹配,获取字符串中所有匹配的子串,并返回一个列表结果。该函数的参数含义如下:

  • pattern:指定需要匹配的正则表达式。
  • string:指定待处理的字符串。
  • flags:指定匹配模式,常用的值可以是re.I、re.M、re.S和re.X。re.I的模式是让正则表达式对大小写不敏感;re.M的模式是让正则表达式可以多行匹配;re.S的模式指明正则符号.可以匹配任意字符,包括换行符\n;re.X模式允许正则表达式可以写得更加详细,如多行表示、忽略空白字符、加入注释等。
2.匹配替换函数

sub(pattern, repl, string, count=0, flags=0)

sub函数的功能是替换,类似于字符串的replace方法,该函数根据正则表达式把满足匹配的内容替换为repl。该函数的参数含义如下:

  • pattern:同findall函数中的pattern。
  • repl:指定替换成的新值。
  • string:同findall函数中的string。
  • count:用于指定最多替换的次数,默认为全部替换。
  • flags:同findall函数中的flags。
3.匹配分割函数

split(pattern, string, maxsplit=0, flags=0)

split函数是将字符串按照指定的正则表达式分隔开,类似于字符串的split方法。该函数的具体参数含义如下:

  • pattern:同findall函数中的pattern。
  • maxsplit:用于指定最大分割次数,默认为全部分割。
  • string:同findall函数中的string。
  • flags:同findall函数中的flags。

如果上面的函数和参数含义都已经掌握了,还需要进一步通过案例加强理解,接下来举例说明上面的三个函数:

如上结果所示,在第一个例子中通过正则表达式"tianqi:'(.*?)'"实现目标数据的获取,如果不使用括号的话,就会产生类似"tianqi:'晴'", "tianqi:'阴~小雨'"这样的值,所以,加上括号就是为了分组,且仅返回组中的内容;第二个例子并没有将正则表达式写入圆括号,如果写上圆括号也是返回一样的结果,所以findall就是用来返回满足匹配条件的列表值,如果有括号,就仅返回括号内的匹配值;第三个例子使用替换的方法,将所有的标点符号换为空字符,进而实现删除的效果;第四个例子是对字符串的分割,如果直接按照正则'[,。、a-zA-Z0-9()]'分割的话,返回的结果中包含空字符,如'2室2厅'后面就有一个空字符。为了删除列表中每个元素的首尾空字符,使用了列表表达式,并且结合字符串的strip方法完成空字符的压缩。