第5章字符串与正则表达式

字符串与正则表达式

字符串

  1.   在Python中字符串属于不可变序列类型,使用单引号、双引号、三单引号或三双引号作为界定符,并且不同的界定符之间可以互相嵌套。
  2.    除了支持序列通用方法(包括双向索引、计算长度、元素访问、切片等操作)以外,字符串类型还支持一些特有的操作方法,如格式化、字符串查找、字符串替换(注意,不是原地替换),排版等。
  3.   字符串提供的replace()和translate()方法也不是对原字符串直接进行修改替换,而是返回一个修改替换后的新字符串作为结果。
  4.   Python支持短字符串驻留机制,对于短字符串,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副本,与其他类型数据具有相同的特点。这一特点并不适合于长字符串,长字符串不遵守驻留机制。
    eg:
    a=‘1234’
    b=‘1234’
    print(id(a)==id(b))
    True

a=‘1234’*50
b=‘1234’*50
print(id(a)==id(b))
False
5. 如果需要判断一个变量是否为字符串,可以使用内置方法isinstance()或type().

6.对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:

ord('A')
65
ord('中')
20013
chr(66)
'B'
chr(25991)
'文'

一、字符串格式化的两种形式

  如果需要将其他类型的数据转换为字符串,或者嵌入其他字符串或模板中再进行输出,就需要用到字符串格式化。格式运算符%之前的部分为格式字符串,之后的部分为需要进行格式化的内容。
'%--------格式标志,表示格式开始
[-]---------指定左对齐输出
[+]--------对正数加正号
[0]--------指定空位填0
[m]-------指定最小宽度
[.n]-------指定精度
格式字符
'%---------格式运算符
x-----------待转换的表达式

Python支持提供大量的格式字符,下面列出了一部分

%s字符串(采用str()的显示)
%r字符串(采用repr()的显示)
%c单个字符
%b二进制整数
%d十进制整数
%i十进制整数
%o八进制整数
%x十六进制整数
%e指数(基地写为e)
%E指数(基地写为E)
%f、%F浮点数
%g指数(e)或浮点数(根据显示长度)
%G指数(E)或浮点数(根据显示长度)
%%字符“%”

除了上面介绍的字符串格式化方法,目前Python社区更推荐使用format()方法进行格式化。
  在字符串格式化方法format()中常用的格式字符。在字符串格式化方法format()中可以使用的格式主要有b(二进制格式)、c(把整数转换成Unicode字符)、d(十进制格式)、o(八进制格式)、x(小写十六进制格式)、X(大写十六进制格式)、e/E(科学记数法格式)、f/F(固定长度的浮点数格式)、%(使用固定长度浮点数显示百分数)
format()它会用传入的参数依次替换字符串内的占位符{0}、{1}……,不过这种方式写起来比%要麻烦得多:

 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

  标准库string还提供了用于字符串格式化的模板类Template。
eg:
t=Template(‘My name is ${name},and is ${age} years old.’) #创建模板
d={‘name’:‘Dong’,‘age’:39}
print(t.substitute(d)) #替换

二、字符串常用方法

1.find()、rfind()、index()、rindex()、count()
  • find()和rfind()方法分别用来查找一个字符串在另一个字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则返回-1
  • index()和rindex()方法用来返回一个字符串在另一个字符串指定范围中首次和最后一次出现的位置,如果不存在则抛出异常
  • count()方法用来返回一个字符串在另一个字符串中出现的次数,如果不存在则返回0
    eg:
    s=“apple,peach,banana,peach,pear”
    print(s.find(“peach”))
    print(s.find(“peach”,7))
    print(s.rfind(‘p’)) #从字符串尾部向前查找
    print(s.index(‘p’)) #返回首次出现的位置
    print(s.count(‘p’)) #统计字符串出现的次数
2.split()、rsplit()、partition()、rpartition()
  •   split()和rsplit()方法分别用来以指定字符为分隔符,从字符串左端和右端开始将其分隔成多个字符串,并返回包含分隔结果的列表
  •   partition()和rpartition()用来以指定字符串和分隔符之后的字符串,如果指定的分隔符不在原字符串中,则返回原字符串和两个空字符串。
s="apple,peach,banana,peach,pear"
print(s.split(","))                 #使用逗号进行分隔
["apple","peach","banana","pear"]
print(s.partition(','))             #从左侧使用逗号进行切分
('apple',',','peach,banana,pear')
print(s.rpartition(','))            #从右侧使用逗号进行切分
('appe,peach,banana',',','pear')
s="2019-7-18"
print(s.split("-"))                 #使用指定字符作为分隔符
['2014','10','31]

  对于split()和rsplit()方法,如果不指定分隔符,则字符串中的任何空白符号(包括空格、换行符、制表符)的连续出现都被认为是分隔符,安徽包含最终分隔结果的列表。

3.join()

  join()方法用来将列表中多个字符串进行连接,并在相邻两个字符串之间插入指定字符。

s=["apple","peach","banana","peach","pear"]
sep=':'
print(sep.join(s))
apple:peach:banana:peach:pear

  使用split()和join()方法可以删除字符串中多余的空白字符,如果有连续多个空白字符,只保留一个。

x='aaa     bb   c d e  fff'
print(' '.join(x.split()))
aaa bb c d e fff

  使用运算符“+”也可以连接字符串,但该运算符涉及大量数据的复制,效率低,不适合大量长字符串的连接。

4.lower()、upper()、capitalize()、title()、swapccase()

  这几个方法分别用来将字符串转换为小写、大写字符串、将字符串首字母变为大写、将每个单词的首字母变为大写以及大小写互换,这几个方法都是生成新字符串,并不对原字符串做任何修改。

s="What is Your Name?"
print(s.lower())     #返回小写字符串
print(s.upper())     #返回大写字符串
print(s.capitalize())#字符串首字符大写
print(s.title())     #将每个单词的首字母大写
print(s.swapcase())  #大小写互换

what is your name?
WHAT IS YOUR NAME?
What is your name?
What Is Your Name?
wHAT IS yOUR nAME?
5.replace()

  该方法用来替换字符串中指定字符或字符串的所有重复出现,每次只能替换一个字符或一个字符串,类似于Word、WPS、记事本等文本编辑器的查找于替换功能。该方法并不能修改原字符串,而是返回一个新字符串。

s="中国,中国"
print(s)
print(s.replace("中国","中华人民共和国"))     
print(s)

中国,中国
中华人民共和国,中华人民共和国
中国,中国

6.maketrans()、translate()

  maketrans()方法用来生成字符映射表,而translate()方法则按映射表中定义的对应关系转换字符串并替换其中的字符,使用这两个方法的组合可以同时处理多个不同的字符,replace()方法则无法满足这一要求。

table=" ".maketrans('abcdef123','uvwxyz@#$')
s="Python is a greate programming language.I like it!"
print(s.translate(table))

Python is u gryuty progrumming lunguugy.I liky it!
 字符串属于不可变对象,不支持原地修改,如果需要修改其中的值,只能重新创建
 一个新的字符串对象。如果确实需要一个支持原地修改的unicode数据对象,可以使用io.StringIO对象或array模块。
7.strip()、rstrip()、lstrip()

  这几个方法分别用来删除两端、右端或左端连续的空白字符或指定字符。

s=" abc "
print(s.strip())
abc
8.eval()

内置函数用来把任意字符串转化为Python表达并进行求值

print(eval("3+4"))
7

  在Python 3.x中,input()用户的输入一律按字符串对待,如果将其还原为本来的类型,可以使用内置函数eval(),有时候可能需要配合异常处理结构。

x=input("please input number:")
357
print(x)
'357'
print(eval(x))
357
9.关键字in

  与列表、元组、字典、集合一样,也可以使用关键字in和not in 来判断一个字符串是否出现在另一个字符串中,返回True或False

print("a"in"abcde")
True
print("ac"in"ancde")
False
10.startswitch()、endswith()

  这两个方法用来判断字符串是否以指定字符串开始或结束,可以接收两个整数参数来限定字符串的检测范围。

s='Beautiful is better than ugly.'
print(s.startswith('Be'))     #检测整个字符串
print(s.startswith('Be',5))   #指定检测范围的起始位置
print(s.startswith('Be',0,5)) #指定检测范围的起始和结束位置

True
False
True

11.isalnum()、isalpha()、isdigit()、isdecimal()、isnumeric()、isspace()、isupper()、islower()

  用来测试字符串是否为数字或字母、是否为字母、是否为数字字符、是否为空白字符、是否为大写字母以及是否为小写字母。

print('1234abcd'.isalnum())  #是否为数字或字母
True
print('1234abcd'.isalpha())  #全部为英文字母时返回True
False

  Python标准库unicodedata提供了不同形式数字字符到十进制数字的转换方法。

print(unicodedata.numeric('2'))   
print(unicodedata.numeric('九'))
2.0
9.0
12.center()、ljust()、rjust()、zfill()

  center()、ljust()、rjust()返回指定宽度的新字符串,原字符串居中、左对齐或右对齐出现在新字符串中,如果指定的宽度大于字符串长度,则使用指定的字符串进行填充,默认以空格进行填充。
zfill()返回指定宽度的字符串,在左侧以字符0进行填充。

print('Hello world!'.center(20))  #居中对齐,以空格进行填充
print('Hello world!'.center(20,'='))  #居中对齐,以字符"="进行填充
print('Hello world!'.ljust(20,'=')) #左对齐
print('Hello world!'.rjust(20,'=')) #右对齐

 Hello world!    
====Hello world!====
Hello world!========
========Hello world!

Python标准库textwrap提供了更加啊友好的排版函数。

doc='''Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than comlex.
Complex is better than complicated.
Flat is better than nested.'''
print(textwrap.fill(doc,width=20))    #按指定宽度进行排版

Beautiful is better
than ugly. Explicit
is better than
implicit. Simple is
better than comlex.
Complex is better
than complicated.
Flat is better than
nested.
13.内置函数、切片

除了字符串对象提供的方法以外,很多Python内置函数也可以对字符串进行操作。

x='Hello world.'
print(len(x))   #字符串长度
print(max(x))   #最大字符
print(min(x))
print(list(zip(x,x))) #zip()也可以用作字符串

12
w
 
[('H', 'H'), ('e', 'e'), ('l', 'l'), ('l', 'l'), ('o', 'o'), 
(' ', ' '), ('w', 'w'), ('o', 'o'), ('r', 'r'), ('l', 'l'), 
('d', 'd'), ('.', '.')]

切片也适用于字符串,但仅限于读取其中的元素,不支持字符串修改。

print('Explicit is better than implicit.'[:8])
print('Explicit is better than implicit.'[9:23])

Explicit
is better than

编写函数实现字符串加密和揭秘,循环使用指定密钥,采用简单的异或算法。

def crypt(source,key):
    from itertools import cycle
    result=''
    temp=cycle(key)
    for ch in source:
        result=result+chr(ord(ch)^ord(next(temp)))
    return result

source='Shandong Institute of Business and Technology'
key='Dong Fuguo'

print('Before Encrypted :'+source)
encrypted=crypt(source,key)
print('After Encrypted:'+encrypted)
decrypted=crypt(encrypted,key)
print('After Decrypted:'+decrypted)

Before Encrypted :Shandong Institute of Business and Technology
After Encrypted:	D)
After Decrypted:Shandong Institute of Business and Technology

Python扩展库jieba和snownlp很好地支持了中文分词,可以使用pip命令进行安装。在自然语言处理领域经常需要对文字进行分词,分词的准确度直接影响了后续文本处理和挖掘算法的最终效果。

正则表达式

   正则表达式由元字符及其不同组合来构成,通过巧妙地构造正则表达式可以匹配任意字符串,并完成复杂的字符串处理任务。

re模块方法与正则表达式对象

  Python 标准库re提供了正则表达式操作所需要的功能,既可以直接使用re模块中的方法来实现字符串处理,也可以把模块编译成正则表达式对象再使用。

compole(pattern[,flags])创建模式对象
search(pattern,string[,flags])在整个字符串中寻找模式,返回match对象或None
match(pattern,string[,flags])从字符串的开始处匹配模式,返回match对象或None
findall(pattern,string[,flags])列出字符串中模式的所有匹配项
split(pattern,string[,maxsplit=0])根据模式匹配项分割字符串
sub(pat,repl,string[,count=0])将字符串中所有pat的匹配项用repl替换
escape(string)将字符串中所有特殊正则表达式字符转义
1.直接使用re模块中的方法
import re
text='alpha.beta...gamma delta'
print(re.split('[\.]+',text))
print(re.split('[\.]+',text,maxsplit=1))
print(re.escape('http://www.python.org'))#字符串转义

2.使用正则表达式对象

首先使用re模块中的compile()方法将正则表达式编译生成正则表达式对象,然后再使用正则表达式对象提供的方法进行字符串处理。

import re
example='ShanDong Institute of Business and Technology'
pattren=re.compile(r'\bB\w+\b') #编译正则表达式,查找以B开头的单词
print(pattren.findall(example))
pattren=re.compile(r'\w+g\b')   #查找以字母g结尾的单词
print(pattren.findall(example))
pattern=re.compile(r'\b[a-zA-Z]{3}\b')  #查找3个字母长的单词
print(pattern.findall(example))
pattern=re.compile(r'\b\w*a\w*\b')  #查找所有含有字母a的单词
print(pattern.findall(example))

import re
example='''Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than comlex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.'''
pattern=re.compile(r'\bb\w* \b',re.I)  #正则表达式对象,匹配以b或B开头的单词
print(pattern.sub('*',example))     #将符合条件的单词替换为*

pattern=re.compile(r'\bb\w* \b') #匹配以字母b开头的单词
print(pattern.sub('*',example,1))   #将符合条件的单词替换为*,只替换一次


example=r'one,two,three.four/five\six?sevev[eight]nine\ten'
pattren=re.compile(r'[,./\\?[\]\|]')   #指定多个可能的分隔符
print(pattern.split(example))
match对象

   正则表达式模块或正则表达式对象的match()方法和search()方法匹配成功后都会返回match()对象。match对象的主要方法有group()(返回匹配的一个或多个子模式内容)、groups()(返回一个包含匹配的所有子模式内容的元组)、groupdict()(返回包含匹配的所有命名子模式内容的字典)、start()(返回指定子模式内容的起始位置)、end()(返回指定子模式内容的结束位置的前一个位置)、span()(返回一个包含指定子模式内容起始位置和结束位置前一个位置的元组)等。

import re
m=re.match(r"(\w+) (\w+)","Isaac Newton,physicist")
print(m.group(0))  #返回整个模式内容
print(m.group(1))  #返回第1个子模式内容
print(m.group(2))  #返回第2个子模式内容
print(m.group(1,2)) #返回指定的多个子模式内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值