自学Python之Python基础:(七)字符串处理技巧

转载的老板请注明出处:http://blog.csdn.net/cc_xz/article/details/78693772万分感谢!

在本篇中,你将了解到:
1.如何拆分字符串。
2.如何判断字符串首尾。
3.如何将多个字符串拼装成一个字符串。
4.如何删除或替换字符串中的字符。

在输出字符串时,可以对字符串进行对齐操作,分别使用:

  • str.ljust():用于向左对齐。
  • str.rjust():用于向右对齐。
  • str.center():用于居中对齐。

以上函数接受两个参数,第一个参数为填充的元素数量,第二个参数为填充的元素类型,默认为空格,例如可以设置等于号、冒号等。


根据分隔符拆分字符串:
拆分单一分隔符字符串:

txt = "123,234\n345,456 567,678"
print(txt.split(","))#默认使用空白例如\n等分割。也可以在参数中输入字符串指定分割。

输出结果为:

['123', '234\n345', '456 567', '678']

这种方式仅适用于只有单一分隔符的情况。

使用正则表达式分割字符串:

import re  # re是正则表达式模块,该模块中包含了很多关于正则表达式的函数。

str01 = "123,432,325.432.123|231|3123/32443、123,2.432,1|324"
"""
split()函数可以根据正则表达式来对字符串(str类型)进行筛选。
在下述代码中,第一个参数是一段正则表达式,第二个参数是需要筛选的字符串。
值得注意的是,split()函数只支持对字符串进行筛选,列表、元组等不支持。
而split()函数返回的类型是一个list
"""
list01 = re.split("[,.|、/]+", str01) 

print(list01)

输出结果为:

['123', '432', '325', '432', '123', '231', '3123', '32443', '123', '2', '432', '1', '324']

当然,更多的正则表达式内容,会在后面单独拿出一篇来进行详细说明。

判断字符串首尾:
生成随机字符串:

from random import sample, randint  # sample用于从列表中抓取随机元素;randint用于生成随机数。

# 定义字母列表,用于随机选择其中的字母组成字符串。
list01 = ["a", "b", "c", "d", "e", "f", "g", "h", "y", "j", "k", "i", "m", "n", "o", "p", "q"]
# 下列推导式为:
# 首先使用for循环20次,即创建索引为0-19的列表。
# 然后使用sample()函数在list01字母列表中随机抓取字母。
# 最后使用randint()函数随机定义每次随机抓取字母的数量。
list02 = [sample(list01, randint(3, len(list01))) for i in range(20)]
list03 = []  # 由于此时list02是2维列表,需要将其转换为1维列表。将最终的元素放到list03中。

for x in range(len(list02)):  # 通过for循环得出list02的索引,进行操作。
   # join()函数可以将一个可迭代对象转换为str字符串,由于此方法是字符串方法,所以需要在前面添加字符串对象。
   str01 = "".join(list02[x])  # 而创建它的字符串对象,可以用于join将可迭代对象转换为str字符串后的分隔符。
   list03.append(str01)

print(list03)

输出结果为:

['fjkpb', 'inpkdeyoqjhcam',.......省略部分结果 'ecak', 'ydkoji']


判断字符串开头或结尾:

from random import sample, randint

list01 = ["a", "b", "c", "d", "e", "f", "g", "h", "y", "j", "k", "i", "m", "n", "o", "p", "q"]
list02 = [sample(list01, randint(3, len(list01))) for i in range(20)]
list03 = []

for x in range(len(list02)):
   str01 = "".join(list02[x])
   list03.append(str01)

for x in list03:
   str(x)
   if x.endswith(("a", "b", "c")):  # 接受一个元组为参数,参数中的所有参数都会依次被用来判断是否以此结尾。
      print("以a或b或c结尾的字符串为:", x)
   elif x.startswith(("a","b","c")):#但endswith()或startswith()只接受字符串或元组为参数,不接受列表等。
      print("以a或b或c开头的字符串为:", x)

输出结果为:

a或b或c开头的字符串为: bqcdpkgaemojfh
以a或b或c结尾的字符串为: iacb
以a或b或c开头的字符串为: cqhfmn
以a或b或c结尾的字符串为: cmeqinofgpdhyb
以a或b或c开头的字符串为: cienm
以a或b或c开头的字符串为: cfbyokjq
以a或b或c开头的字符串为: aoehgkfmn
以a或b或c开头的字符串为: agnohpiycdqjk
以a或b或c结尾的字符串为: gimkc


调整字符串文本格式:
如果我们期望将一些字符串(例如log、更新信息等)中的内容调整格式,可以使用re.sub()函数。re.sub()函数可以用于字符串替换,利用正则表达式的捕获组,捕获字符串中所有的内容,根据匹配成功的内容,在根据定义好的结果顺序进行重新排序。
例如现在打开一个更新文件,修改日期的显示格式:

import re

txt = open("Release.txt","r",encoding="utf-8").read()
#txt = re.sub("(\d{4})-(\d{2})-(\d{2})",r"\2/\3/\1",txt)
"""
sub()函数接受3个参数,第一个参数是一段正则表达式,用于选定需要修改格式的目标元素。
第二个元素也是一段正则表达式,用于设置将元素修改成何种格式。
第三个元素是则是要修改的目标字符串。
而第一个sub()函数和第二个sub()函数的区别在于,第二个函数通过正则表达式给各个字段起了一个别名,而在第二个参数中通过别名来选择目标元素。
"""
txt = re.sub("(?P\d{4})-(?P\d{2})-(?P\d{2})",r"\g/\g/\g/",txt)
print(txt)

输出结果为:

日期:08/07/2012/
日期:12/20/2011/
日期:2011-2-16
日期:04/13/2010/
日期:11/20/2009/
日期:10/27/2009/
日期:2009-6-29

上述结果,我们可以发现,在正则表达式中,定义的第二、第三个字段都是2个字节的,而在日期中,凡事同定义的字节数相同的,均被转换了格式,而字节数不同的,则没有成功匹配。

将多个字符串拼装成一个字符串:
当处理一些参数时,可能会需要将将多个零散的字符串(可能是参数什么的)拼装成一个字符串。最简单的方式为:

list01 = ["<3389>", "", "<23ms>", "<1024k>", "<202.106.0.20>", "<49>"]  # 定义一些参数放到列表中。
str01 = ""  # 定义一个空字符串,用于迭代后的参数放入其中。

for x in list01:  # 列表经过迭代后返回的结果x本身即为str类型。
   str01 += x  # 如果列表中的值均为str类型,此种方法可行,但如果存在其他类型,例如int类型等,则需要强制转型。
   print(str01)

输出结果为:

<3389>
<3389><TCP/IP>
<3389><TCP/IP><23ms>
<3389><TCP/IP><23ms><1024k>
<3389><TCP/IP><23ms><1024k><202.106.0.20>
<3389><TCP/IP><23ms><1024k><202.106.0.20><49>


使用join()函数拼装字符串:

list01 = ["<3389>", "", "<23ms>", "<1024k>", "<202.106.0.20>", "<49>"]  # 定义一些参数放到列表中。
str01 = "|".join(list01) #join()函数可以将一个可迭代对象转换为str字符串,由于此方法是字符串方法,所以需要在前面添加字符串对象。
# 而创建它的字符串对象,可以用于join将可迭代对象转换为str字符串后的分隔符。
print(str01)

输出结果为:

<3389>|<TCP/IP>|<23ms>|<1024k>|<202.106.0.20>|<49>


字符串相加和join()拼装耗时:

import time
from random import sample

"""
首先通过列表推导式创建一个长度为100万的二维了列表,每个列表中都有5个子列表。
但二维列表并不能直接被join()函数和for遍历,所以再将对二维列表进行处理,作为普通列表。
列表长度为100万,每个列表元素中有5个字符串。
"""
list01 = [sample("qwertyuiop", 5) for x in range(1, 1000001)]
list02 = []

for x in range(len(list01)):
   str00 = ''.join(list01[x])
   list02.append(str00)

"""
首先确定使用join()函数所需的时间:
首先通过time.clock()函数获得当前时间(开始时间),放到一个变量中。
然后使用join()对列表进行处理,将最终的结果放置到str01变量中(str类型)。
接着再记录当前的时间作为结束时间,再放到一个变量中。
最后使用结束的时间减去开始的时间,最终得出耗时。
"""
startTime01 = time.clock()
str01 = "".join(list02)
endTime01 = time.clock()
joinTime01 = endTime01 - startTime01
print(joinTime01, "joinTime01")

""" 
然后确定使用for遍历配合字符串相加的方式:
同上,首先确定当前的开始时间,然后定义一个空字符串,用于放置需要处理的字符串。
然后使用for循环,对list进行遍历,然后使用+=符号,将遍历出的字符串放置到字符串中。
最后是确定结束时间,再得出所需的耗时。
"""
startTime02 = time.clock()
str02 = ""
for i in list02:
   str02 += i  # 实际上+=操作是调用了字符串的__add__()函数。
endTime02 = time.clock()
joinTime02 = endTime02 - startTime02
print(joinTime02, "joinTime02")

输出结果为:

0.017965127833818366 joinTime01
1.984568595269575 joinTime02

其实耗时最长的是创建这个长度为百万的列表………


删除字符串中的字符:
可以用于删除字符串中特定字符的方法有:
1. 字符串的strip()、lstrip()、rstrip(),用于去掉字符串两端的字符。
2. 使用切片+拼接的方式,可以删除单个固定位置的字符。
3. 字符串的replace()函数或正则表达式的re.sub()函数可以删除任意位置的字符。
4. 字符串的translate()函数可以同时删除多种不同的字符。
使用strip()、lstrip()、restrip()删除两端字符:

str01 = "  这是一段字符串,前有2个空白字符,后有3个空白字符串   "

str02 = str01.strip()  # 默认删除前后两端所有的空白字符。
str03 = str02.strip("空白字符串")  # 也可以用来删除前后位置指定的字符串。
str04 = str02.strip("空白")  # 但是指定字符如果没有在首尾位置,则不会删除。
str05 = str02.strip("这是字符串")  # 参数中的字符分别在首尾位置,但strip()仍能识别。
print(str02, "\n", str03, "\n", str04, "\n", str05)

str01 = "---test+++++"
str02 = str01.strip("+-")  # 只要参数中的字符被前后包含,则都会删除。
print(str02)

输出结果为:

这是一段字符串,前有2个空白字符,后有3个空白字符串 
 这是一段字符串,前有2个空白字符,后有3个 
 这是一段字符串,前有2个空白字符,后有3个空白字符串 
 一段字符串,前有2个空白字符,后有3个空白
test

而剩下的lstrip()和rstrip()同strip()的作用相同,区别在于,strip()是会对首尾两端符合条件的字符进行删除,而lstrip()和rstrip()仅会分别对左右一端的字符进行删除。


使用切片和拼接的删除字符:

str01 = "abc:123"
str02 = str01[:3] + str01[4:]  # 使用切片略过希望删除的部分。
print(str02)

输出结果为:

abc123


使用replace()函数或re.sub()函数替换字符:

from re import sub  # 仅导入re包中的sub()函数

str01 = "abc\tcbd\nxyz"
str02 = str01.replace("\t", "-")  # 可以在字符串中筛选目标字符串和替换成的字符串。
# 但replace()在同一个函数中只能替换一次。上例中的\n则无法在同一个函数中剔除。
print(str02)

# 使用正则表达式中的sub()函数替换字符串中的字符。
# 首先定义筛选的规则(正则表达式),然后定义替换成何种类型的字符。
# 最后将需要被筛选的字符串作为参数传递给sub()函数。
str03 = sub("[\t\n]", "-", str01)
print(str03)

输出结果为:

abc-cbd
xyz
abc-cbd-xyz


使用字符串translate()函数剔除多个字符:
关于2.X和3.X两个版本中的maketrans()和translate()两个函数的区别简单介绍下:
Python3.X中,对字符串进行了重新划分,分为了字节字符(bytes)和文本字符串(str),由于两者都是不可变的,所以添加了一个可变的字节字符串类型(bytearray)。由于在2.X版本中,string类型和str、unicode中很多的函数都是重复的,所以在3.X版本中不提倡使用string类型。

"""
maketrans()函数用于创建“字符映射关系转换表”,这个转换表用于将源字符转换成目标字符。
maketrans()函数接收两个参数:
第一个参数是一段字符串,表示需要转换的字符,即源字符。
第二个参数也是一段字符串,表示需要转换成何种字符,即目标字符。
而两个字符串的长度必须相等,用于保证对应关系。
"""
inTab = "abcd"
outTab = "1234"
strSwitchTab = str.maketrans(inTab, outTab)  # bytes()等函数中也有该方法。

# translate()函数将根据maketrans()函数返回的“字符映射关系转换表”,对使用该函数的字符串进行转换。
textStr = "这a是B一c段D测b试"
textStr = textStr.translate(strSwitchTab)
print(textStr)

"""
而在Python3.0+的版本中,如果希望删除任意字符,则需要在maketrans()函数的第三个参数中定义。
如果不希望替换其他元素,则将前两个参数定义为空字符串。而在第三个参数中定义需要删除的字符。
值得注意的是,在这种操作中,translate()函数不会区分你定义的需删除字符串是一个“单词”还是“字母”。
它会将你输入的所有字符同字符串中的所以字符进行相匹配,如果相同,则直接删除。
"""
textStr = "这a是B一c段D测b试DacbB"
strDelTab = str.maketrans("","","DacbB")
textStr = textStr.translate(strDelTab)
print(textStr)

输出结果为:

1是B一3D2试
这是一段测试


字符串类型:
Python3非常重要的新特性之一就是将文本和二进制数据做了非常清晰的区分,文本总是Unicode的,使用str表示。二进制数据则由bytes类型来表示。Python3 不会使用任何隐式的方式来混用str和bytes,例如,你无法将字符串和字节包拼装到一起,也无法在字节包中搜索某个字符串。
但字符串是可以解码为字节包的,而字节包也可以解码为字符串。

text = "一段中文字符"
text = text.encode("UTF-8")  # 将str字符串解码成二进制字节包
print(text)
text = text.decode("UTF-8")  # 再将二进制字节包转码成str字符串
print(text)

输出结果为:

b'\xe4\xb8\x80\xe6\xae\xb5\xe4\xb8\xad\xe6\x96\x87\xe5\xad\x97\xe7\xac\xa6'
一段中文字符

编码(上面的UTF-8)是这个转换过程中至关重要的一部分,脱离了编码,二进制字节包就是一堆比特位而已,是编码赋予其含义,因此采用不同的编码,这堆比特位的含义也不尽相同。


字符串前字母的含义:

"""
在字符串前添加u,表示对字符串进行unicode编码。
一般英文字符在各种编码下都可以正常解析,所以一般不带u;但是中文字符串,必须明确表明所需的编码,
否则转码时就会出现乱码。
值得注意的是,UTF-8是unicode的一种实现方式。
"""
str01 = u"这是一段字符串"
print(str01)

"""
在字符串前添加r,表示非转义的原始字符串。
在字符串中,可能会有一些转意符,长见的有“\n”,“\t”等,但如果该字符串以r开头,
则说明在这个字符串中所有的其他字符,都是普通字符。
"""
str02 = r"这是一段\n字符串"
print(str02)

"""
在字符串前添加b,表示是bytes二进制编码。
"""
byte = b"testCode"
print(byte)
print(type(byte))

输出结果为:

这是一段字符串
这是一段\n字符串
b'testCode'
<class 'bytes'>

你可能感兴趣的:(自学之路之Python基础)