PYTHON字符串
(这个操作现在基本不用)
(使用format方法,也不怎么用)
'''使用format方法进行格式化
>>> print(“The number {0:,} in hex is: {0:#x}, the number {1} in oct is{1:#o}”.format(5555,55)) #使用位置进行格式化
The number 5,555 in hex is: 0x15b3, the number 55 in oct is 0o67
>>> print("The number {1:,} in hex is: {1:#x}, the number {0} in oct is {0:o}".format(5555,55))
The number 55 in hex is: 0x37, the number 5555 in oct is 12663
>>> print(“my name is {name}, my age is {age}, and my QQ is {qq}”.format(name=“Dong Fuguo”,age=40,qq=“30646****”)) #使用参数名字进行格式化
my name is Dong Fuguo, my age is 40, and my QQ is 30646****
>>> position = (5, 8, 13)
>>> print(“X:{0[0]};Y:{0[1]};Z:{0[2]}”.format(position)) #使用序列解包
X:5;Y:8;Z:13
>>> '{0:<8d},{0:^8d},{0:>8d}'.format(65) #设置对齐方式
'65 , 65 , 65
>>> '{0:+<8d},{0:-^8d},{0:=>8d}'.format(65)
'65++++++,---65---,======65'
从Python 3.6.x开始支持一种新的字符串格式化方式,官方叫做Formatted String Literals,简称f-字符串,在字符串前加字母f,含义与字符串对象 format()方法类似。在进行格式化时,使用前面定义的同名变量的值对格式化 字符串中的占位符进行替换。
width = 8
>>> height = 6
>>> print(f'Rectangle of {width}*{height}\nArea:{width*height}')
Rectangle of 8*6
Area:48
find()、rfind()、index()、rindex()、count()
find()和rfind方法分别用来查找一个字符串在另一个字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则返回-1;
index()和rindex()方法用来返回一个字符串在另一个字符串指定范围中首次和最后一次出现的位置,如果不存在则抛出异常;
count()方法用来返回一个字符串在当前字符串中出现的次数
>>> s="apple,peach,banana,peach,pear"
>>> s.find("peach")
6
>>> s.find("peach",7)
19
>>> s.find("peach",7,20)
-1
>>> s.rfind('p')
25
>>> s.index('p')
1
>>> s.index('pe')
6
>>> s.index('pear')
25
>>> s.index('ppp')
Traceback (most recent calllast):
File "<pyshell#11>", line 1,in <module>
s.index('ppp')
ValueError: substring not found
>>> s.count('p')
5
>>> s.count('pp')
1
>>> s.count('ppp')
0
split()、rsplit()、partition()、rpartition()
split()和rsplit()方法分别用来以指定字符为分隔符,把当前字符串从左往右或从右往左分隔成多个字符串,并返回包含分隔结果的列表;(对于split()和rsplit()方法,如果不指定分隔符,则字符串中的任何空白符号(空格、换行符、制表符等)都将被认为是分隔符,并删除切分结果中的空字符串。)然而,明确传递参数指定split()使用的分隔符时,情况是不一样的,会保留切分
得到的空字符串。
partition()和rpartition()用来以指定字符串为分隔符将原字符串分隔为3部分,即分 隔符前的字符串、分隔符字符串、分隔符后的字符串,如果指定的分隔符不在原字符串 中,则返回原字符串和两个空字符串
>>> s = "apple,peach,banana,pear"
>>> s.split(",")
["apple", "peach", "banana", "pear"]
>>> s.partition(',')
('apple', ',', 'peach,banana,pear')
>>> s.rpartition(',')
('apple,peach,banana', ',', 'pear')
>>> s.rpartition('banana')
('apple,peach,', 'banana', ',pear')
>>> s = "2017-10-31"
>>> t = s.split("-")
>>> print(t)
['2017', '10', '31']
>>> print(list(map(int, t)))
[2017, 10, 31]
对于split()和rsplit()方法,如果不指定分隔符,则字符串中的任何空白符
>>> s = 'hello world \n\n My name is Dong '
>>> s.split()
['hello', 'world', 'My', 'name', 'is', 'Dong']
>>> s = '\n\nhello world \n\n\n My name is Dong '
>>> s.split()
['hello', 'world', 'My', 'name', 'is', 'Dong']
>>> s = '\n\nhello\t\t world \n\n\n My name\t is Dong '
>>> s.split()
['hello', 'world', 'My', 'name', 'is', 'Dong']
然而,明确传递参数指定split()使用的分隔符时,情况是不一样的,会保留切分得到的空字符串。
>>> 'a,,,bb,,ccc'.split(',') #每个逗号都被作为独立的分隔符
['a', '', '', 'bb', '', 'ccc']
>>> 'a\t\t\tbb\t\tccc'.split('\t') #每个制表符都被作为独立的分隔符
['a', '', '', 'bb', '', 'ccc']
>>> 'a\t\t\tbb\t\tccc'.split() #连续多个制表符被作为一个分隔符
['a', 'bb', 'ccc']
split()和rsplit()方法还允许指定最大分割次数。
>>> s = '\n\nhello\t\t world \n\n\n My name is Dong '
>>> s.split(None, 1) #不指定分隔符,使用空白字符作为分隔符
['hello', 'world \n\n\n My name is Dong ']
>>> s.rsplit(None, 1)
['\n\nhello\t\t world \n\n\n My name is', 'Dong']
>>> s.split(None, 2)
['hello', 'world', 'My name is Dong ']
>>> s.rsplit(None, 2)
['\n\nhello\t\t world \n\n\n My name', 'is', 'Dong']
>>> s.split(maxsplit=6)
['hello', 'world', 'My', 'name', 'is', 'Dong']
>>> s.split(maxsplit=100) #最大分隔次数大于可分隔次数时无效
['hello', 'world', 'My', 'name', 'is', 'Dong']
字符串连接join()
用来将可迭代对象中多个字符串进行连接,并在相邻两个字符之间插入指定字符串。 (不推荐使用+运算符连接字符串,优先使用join()方法。时间大约相差十倍)
>>> 'apple,peach,banana,pear'
>>> '.'.join(li)
'apple.peach.banana.pear'
>>> '::'.join(li)
'apple::peach::banana::pear'
if __name__ == '__main__':
测一下效率差
#重复运行次数
times = 1000
jointimer = timeit.Timer('use_join()', 'from __main__ import use_join')
print('time for join:', jointimer.timeit(number=times))
plustimer = timeit.Timer('use_plus()', 'from __main__ import use_plus')
print('time for plus:', plustimer.timeit(number=times))
lower()、upper()、capitalize()、title()、swapcase()
>>> s = "What is Your Name?"
>>> s.lower() #返回小写字符串
'what is your name?'
>>> s.upper() #返回大写字符串
'WHAT IS YOUR NAME?'
>>> s.capitalize() #字符串首字符大写
'What is your name?'
>>> s.title() #每个单词的首字母大写
'What Is Your Name?'
>>> s.swapcase() #大小写互换
'wHAT IS yOUR nAME?'
查找替换replace(),该方法用来替换指定字符或字符串的所有重复出现,每次只能替换一个字符或字符串。
>>> words = ('测试', '非法', '暴力', '话')
>>> text = '这句话里含有非法内容'
>>> for word in words:
if word in text:
text = text.replace(word, '***')
>>> text
'这句***里含有***内容'
字符串对象的maketrans()方法用来生成字符映射表,而translate()方法用来根据映射表中定义的对应关系转换字符串并替换其中的字符,使用这两个方法的组合可以同时处理多个字符。
#创建映射表,将字符"abcdef123"一一对应地转换为"uvwxyz@#$"
>>> table = ''.maketrans('abcdef123', 'uvwxyz@#$')
>>> s = "Python is a great programming language. I like it!"
>>> s.translate(table) #按映射表进行替换
'Python is u gryut progrumming lunguugy. I liky it!'
>>> table = ''.maketrans('0123456789', '零一二三四伍陆柒捌玖')
>>> ‘2022年3月22日'.translate(table)
'二零二二年三月二二日'
strip()、rstrip()、lstrip()
用来剔除字符串两端、右侧或左侧的空白字符或指定字符。
>>> s = " abc "
>>> s.strip() #删除空白字符
'abc'
>>> '\n\nhello world \n\n'.strip() #删除空白字符
'hello world'
>>> "aaaassddf".strip("a") #删除指定字符
'ssddf'
>>> "aaaassddf".strip("af")
'ssdd'
>>> "aaaassddfaaa".rstrip("a") #删除字符串右端指定字符
'aaaassddf'
>>> "aaaassddfaaa".lstrip("a") #删除字符串左端指定字符
'ssddfaaa'
这三个方法的参数指定的字符串并不作为一个整体对待,而是在原字符串的两侧、右侧、左侧删除参数字符串中包含的所有字符,一层一层地从外往里扒。
>>> 'aabbccddeeeffg'.strip('af') #字母f不在字符串两侧,所以不删除
'bbccddeeeffg'
>>> 'aabbccddeeeffg'.strip('gaf')
'bbccddeee'
>>> 'aabbccddeeeffg'.strip('gaef')
'bbccdd'
>>> 'aabbccddeeeffg'.strip('gbaef')
'ccdd'
>>> 'aabbccddeeeffg'.strip('gbaefcd')
''
内置函数eval()
尝试把任意字符转化为Python表达式并求值。
>>> eval("3+4") #计算表达式的值
7
>>> a = 3
>>> b = 5
>>> eval('a+b') #要求变量a和b已存在
8
>>> import math
>>> eval('math.sqrt(3)')
1.7320508075688772
>>> eval('aa') #当前上下文中不存在对象aa
NameError: name 'aa' is not defined
>>> eval('*'.join(map(str, range(1, 6)))) #5的阶乘
120
>>> a = input("Please input:")
Please input:__import__('os').startfile(r'C:\Windows\notepad.exe')
>>> eval(a)
>>>
>>> eval(“__import__(‘os’).system(‘md testtest’)”) #创建文件夹testtest
0
>>> eval(“__import__(‘os’).system(‘rd testtest’)”) #删除文件夹testtest
0
成员判断,关键字in
>>> "a" in "abcde" #测试一个字符中是否存在于另一个字符串中
True
>>> 'ab' in 'abcde'
True
>>> 'ac' in 'abcde' #关键字in左边的字符串作为一个整体对待
False
>>> "j" in "abcde"
False
Python字符串支持与整数的乘法运算,表示序列重复,也就是字符串内容的重复,得到新字符串。
>>> 'abcd' * 3
'abcdabcdabcd'
startswith()、endswith(),判断字符串是否以指定字符串开始或结束
>>> s = 'Beautiful is better than ugly.'
>>> s.startswith('Be') #检测整个字符串
True
>>> s.startswith('Be', 5) #指定检测范围起始位置
False
>>> s.startswith('Be', 0, 5) #指定检测范围起始和结束位置
True
>>> import os
>>> [filename for filename in os.listdir(r'c:\\')
if filename.endswith(('.bmp','.jpg','.gif'))]
center()、ljust()、rjust(),返回指定宽度的新字符串,原字符串居中、左对齐或右对齐出现在新字符串中,如果指定宽度大于字符串长度,则使用指定的字符(默认为空格)进行填充。
>>> 'Hello world!'.center(20) #居中对齐,以空格进行填充
' Hello world! '
>>> 'Hello world!'.center(20, '=') #居中对齐,以字符=进行填充
'====Hello world!===='
>>> 'Hello world!'.ljust(20, '=') #左对齐
'Hello world!========'
>>> 'Hello world!'.rjust(20, '=') #右对齐
'========Hello world!'
salnum()、isalpha()、isdigit()、isdecimal()、isnumeric()、isspace()、isupper()、islower()
用来测试字符串是否为数字或字母、是否为字母、是否为数字字符、是否为空白字符、是否为大写字母以及是否为小写字母。
>>> '1234abcd'.isalnum()
True
>>> '1234abcd'.isalpha() #全部为英文字母时返回True
False
>>> '1234abcd'.isdigit() #全部为数字时返回True
False
>>> 'abcd'.isalpha()
True
>>> '1234.0'.isdigit()
False
>>> '1234'.isdigit()
True
>>> '九'.isnumeric() #isnumeric()方法支持汉字数字
True
>>> '九'.isdigit()
False
>>> '九'.isdecimal()
False
>>> 'ⅣⅢⅩ'.isdecimal()
False
>>> 'ⅣⅢⅩ'.isdigit()
False
>>> 'ⅣⅢⅩ'.isnumeric() #支持罗马数字
True
除了字符串对象提供的方法以外,很多Python内置函数也可以对字符串进行操作,例如:
>>> x = 'Hello world.'
>>> max(x), min(x), len(x)
('w', ' ', 12)
>>> max(['abc', 'ABD'], key=str.upper) #忽略大小写
'ABD'
>>> sorted(x)
[' ', '.', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']
>>> list(zip(x,x)) #zip()也可以作用于字符串
[('H', 'H'), ('e', 'e'), ('l', 'l'), ('l', 'l'), ('o', 'o'), (' ', ' '), ('w', 'w'), ('o', 'o'), ('r', 'r'), ('l', 'l'), ('d', 'd'), ('.', '.')]
>>> eval('[1, 2, 3, 4]')
#字符串求值
[1, 2, 3, 4]
切片也适用于字符串,但仅限于读取其中的元素,不支持字符串修改。
>>> 'Explicit is better than implicit.'[:8]
'Explicit'
>>> 'Explicit is better than implicit.'[9:23]
'is better than'
Python标准库string中定义数字字符、标点符号、英文字母、大写字母、小写字母等常量。
>>> import string
>>> string.digits #数字字符
'0123456789'
>>> string.punctuation #标点符号
'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
>>> string.ascii_letters #英文字母
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> string.ascii_lowercase
'abcdefghijklmnopqrstuvwxyz'
>>> string.ascii_uppercase
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
random库主要用于生成随机数,random库包括两类函数,常用的有:
ü 基本随机数函数: seed(), random()
ü 扩展随机数函数: randint(), getrandbits(), uniform(), randrange(), choice(),
shuffle(),sample()
– seed(a=None) 初始化给定的随机数种子,默认为当前系统时间
– random() 生成一个[0.0, 1.0)之间的随机小数 – randint(a, b) 生成一个[a, b]之间的整数
– randrange(m, n[, k]) 生成一个[m, n)之间以k为步长的随机整数 – getrandbits(k) 生成一个k比特长的随机整数 – uniform(a, b) 生成一个[a, b]之间的随机小数
– choice(seq) 从序列seq中随机选择一个元素
– sample(seq,k) 从序列seq中随机选择指定数量的不重复元素
– shuffle(seq) 将序列seq中元素随机排列,返回打乱后的序列
在Python中,字符串属于不可变对象,不支持原地修改,如果需要修改其中的值,只能重新创建一个新的字符串对象。然而,如果确实需要一个支持原地修改的unicode数据对象,可以使用io.StringIO对象或array模块
>>> import io
>>> s = "Hello, world"
>>> sio = io.StringIO(s)
>>> sio.getvalue()
'Hello, world'
>>> sio.seek(7)
7
>>> sio.write("there!")
6
>>> sio.getvalue()
'Hello, there!'
中文
在处理中文文本时,需要通过分词获得单个的词语。jieba是优秀的中文分词第三方
库需要额外安装
jieba分词的三种模式 精确模式、全模式、搜索引擎模式
-
精确模式:把文本精确的切分开,不存在冗余单词 jieba.lcut(s) 精确模式,返回一个列表类型的分词结果
-
全模式:把文本中所有可能的词语都扫描出来,有冗余 jieba.lcut(s, cut_all=True) 全模式,返回一个列表类型的分词结果,存在冗余
-
搜索引擎模式:在精确模式基础上,对长词再次切分 jieba.lcut_for_search(s) 搜索引擎模式,返回一个列表类型的分词结果,存在冗余
>>> import jieba #导入jieba模块 >>> x = '分词的准确度直接影响了后续文本处理和挖掘算法的最终效果。' >>> jieba.cut(x) #使用默认词库进行分词 <generator object Tokenizer.cut at 0x000000000342C990> >>> list(_) ['分词', '的', '准确度', '直接', '影响', '了', '后续', '文本处理', '和', '挖 掘', '算法', '的', '最终', '效果', '。'] >>> jieba.lcut('Python可以这样学,Python程序设计开发宝典') #直接给出列表 Dumping model to file cache C:\Users\d\AppData\Local\Temp\jieba.cache ['Python', '可以', '这样', '学', ',', 'Python', '程序设计', '开发', '宝典'] >>> list(jieba.cut('花纸杯')) ['花', '纸杯'] >>> jieba.add_word('花纸杯') #增加词条 >>> list(jieba.cut('花纸杯')) #使用新词库进行分词 ['花纸杯'] >>> from jieba import posseg >>> text = '分词的准确度直接影响了后续文本处理和挖掘算法的最终效果。' >>> for word, tag in posseg.cut(text): # 得到分词及其词性 print(word, tag, sep=':', end='\t') 分词:n 的:uj 准确度:n 直接:ad 影响:vn 了:ul 后续:v 文本处理:n 和:c 挖掘:v 算法:n 的:uj 最终:d 效果:n 。:x拼音处理
>>> from pypinyin import lazy_pinyin, pinyin >>> lazy_pinyin('董付国') #返回拼音 ['dong', 'fu', 'guo'] >>> lazy_pinyin('董付国', 1) #带声调的拼音 ['dǒng', 'fù', 'guó'] >>> lazy_pinyin('董付国', 2) #另一种拼音形式,数字表示前面字母的声调 ['do3ng', 'fu4', 'guo2'] >>> lazy_pinyin('董付国', 3) #只返回拼音首字母 ['d', 'f', 'g'] >>> lazy_pinyin('重要', 1) #能够根据词组智能识别多音字 ['zhòng', 'yào'] >>> lazy_pinyin('重阳', 1) ['chóng', 'yáng'] >>> pinyin('重阳') #返回拼音 [['chóng'], ['yáng']] >>> pinyin('重阳节', heteronym=True) #返回多音字的所有读音 [['zhòng', 'chóng', 'tóng'], ['yáng'], ['jié', 'jiē']] >>> import jieba #其实不需要导入jieba,这里只是说明已安装 >>> x = '中英文混合test123' >>> lazy_pinyin(x) #自动调用已安装的jieba扩展库分词功能 ['zhong', 'ying', 'wen', 'hun', 'he', 'test123'] >>> lazy_pinyin(jieba.cut(x)) ['zhong', 'ying', 'wen', 'hun', 'he', 'test123'] >>> x = '山东烟台的大樱桃真好吃啊' >>> sorted(x, key=lambda ch: lazy_pinyin(ch)) #按拼音对汉字进行排序 ['啊', '吃', '大', '的', '东', '好', '山', '台', '桃', '烟', '樱', '真']
正则表达式
正则表达式使用某种预定义的模式去匹配一类具有共同特征的字符串,主要用 于处理字符串,可以快速、准确地完成复杂的查找、替换等处理要求,在文本 编辑与处理、网页爬虫之类的场合中有重要应用
正则表达式语法
最简单的正则表达式是普通字符串,可以匹配自身
'[pjc]ython'可以匹配'python'、'jython'、'cython'
'[a-zA-Z0-9]'可以匹配一个任意大小写字母或数字
'python|perl'或'p(ython|erl)'都可以匹配'python'或'perl'
子模式后面加上问号表示可选。r'(http://)?(www\.)?python\.org'只能匹配
'http://www.python.org'、'http://python.org'、'www.python.org'和'python.org'
(pattern)*:允许模式重复0次或多次
(pattern)+:允许模式重复1次或多次
(pattern){m,n}:允许模式重复m~n次
'(a|b)*c':匹配多个(包含0个)a或b,后面紧跟一个字母c。
'ab{1,}':等价于'ab+',匹配以字母a开头后面带1个至多个字母b的字符串。
'^[a-zA-Z]{1}([a-zA-Z0-9._]){4,19}$':匹配长度为5-20的字符串,必须以字母开头并且可带字母、数字、“_”、“.”的字符串。
'^(\w){6,20}$':匹配长度为6-20的字符串,可以包含字母、数字、下划线。
'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$':检查给定字符串是否为合法IP地址。
r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$':检查给
定字符串是否为手机号码。
'^[a-zA-Z]+$':检查给定字符串是否只包含英文字母大小写。
'^\w+@(\w+\.)+\w+$':检查给定字符串是否为合法电子邮件地址。
Python中,re模块提供了正则表达式操作所需要的功能。
>>> example = 'Beautiful is better than ugly.'
>>> re.findall('\\bb.+?\\b', example) #以字母b开头的完整单词
#此处问号?表示 **非贪心模式**
['better']
>>> re.findall('\\bb.+\\b', example) #贪心模式的匹配结果
['better than ugly']
>>> re.findall('\\bb\w*\\b', example)
['better']
>>> re.findall('\\Bh.+?\\b', example)
#不以h开头且含有h字母的单词剩余部分
['han']
>>> re.findall('\\b\w.+?\\b', example) #所有单词
['Beautiful', 'is', 'better', 'than', 'ugly']
实例——爬虫