Pandas学习(5.3 字符串对象方法,含正则表达式)

import pandas as pd

'''5.3.1 字符串对象方法'''
'''在很多字符串处理和脚本应用中,内建的字符串方法是足够的。例如,一个逗号分隔的字符串可以使用split方法拆分成多块:'''
val = 'a,b,  guido'
# print(val.split(',')) #['a', 'b', '  guido']

'''split常和strip一起使用,用于清除空格(包括换行):'''
pieces = [x.strip() for x in val.split(',')]
# print(pieces) #['a', 'b', 'guido']

'''这些子字符串可以使用加法与两个冒号分隔符连接在一起:'''
first, second, third = pieces
# print(first + '::' + second + '::' + third) #a::b::guido

'''但是这并不是一个实用的通用方法。在字符串'::'的join方法中传入一个列表或元组是一种更快且更加Pythonic的方法:'''
# print('::'.join(pieces)) #a::b::guido

'''使用Python的in关键字是检测子字符串的最佳方法,尽管index和find也能实现同样的功能:'''
# print('guido' in val) #True
# print(val.index(',')) #1
# print(val.find(':')) #-1
'''请注意find和index的区别在于index在字符串没有找到时会抛出一个异常(而find是返回-1)'''

'''count返回的是某个特定的子字符串在字符串中出现的次数:'''
# print(val.count(',')) #2

'''replace将用一种模式替代另一种模式。它通常也用于传入空字符串来删除某个模式'''
# print(val.replace(',', '::')) #a::b::  guido
# print(val.replace(',', '')) #ab  guido

'''
表:Python内建字符串方法
方法                  描述
count           返回子字符串在字符串中的非重叠出现次数
endswith        如果字符串以后缀结尾则返回True
startswith      如果字符串以前缀开始则返回True
join            使用字符串作为间隔符,用于粘合其他字符串的序列
index           如果在字符串中找到,则返回子字符串中第一个字符的位置;如果找不到则引发ValueError
find            返回字符串中第一个出现子字符的第一个字符的位置;类似index,但如果没有找到则返回-1
rfind           返回子字符串在字符串中最后一次出现时第一个字符的位置;如果没有找到,则返回-1
replace         使用一个字符串替代另一个字符串
strip,rstrip,lstrip 修剪空白,包括换行符;相当于对每个元素进行x.strip()(以及rstrip, lstrip)
split           使用分隔符将字符串拆分为子字符串的列表
lower           将大写字母转换为小写字母
upper           将小写字母转换为大写字母
casefold        将字符转换为小写,并将任何特定于区域的变量字符组合转换为常见的可比较形式
                注:lower() 方法只对ASCII编码,也就是‘A-Z’有效,对于其他语言(非汉语或英文)中把大写转换为小写的情况只能用 casefold() 方法
ljust,rjust     左对齐或右对齐;用空格(或其他一些字符)填充字符串的相反侧以返回具有最小宽度的字符串
'''
#ljust和rjust的案例:
string = 'This is a test string!'
# print(string.ljust(30, '!')) #This is a test string!!!!!!!!!
# print(string.rjust(30, '>')) #>>>>>>>>This is a test string!

'''5.3.2 正则表达式'''
'''re模块主要有三个主题:模式匹配、替代、拆分。
假设我们想讲含有多种空白字符(制表符、空格、换行符)的字符串拆分开。描述一个或多个空白字符的正则表达式是 \s+ :'''
import re
text = "foo     bar\t baz   \tqux"
# print(re.split('\s+', text)) #['foo', 'bar', 'baz', 'qux']

'''当调用re.split('\s+', text),正则表达式首先会被编译,然后正则表达式的split方法在传入文本上被调用。
你可以使用re.compile自行编译,形成一个可复用的正则表达式对象:'''
regex = re.compile('\s+')
# print(regex.split(text)) #['foo', 'bar', 'baz', 'qux']

'''如果你想获得的是一个所有匹配正则表达式的模式的列表,你可以使用findall方法:'''
# print(regex.findall(text)) #['     ', '\t ', '   \t']

'''如果需要将相同的表达式应用到多个字符串上,推荐使用re.compile创建一个正则表达式对象,这样做有利于节约CPU周期。'''
'''match和search与findall相关性很大。findall返回的是字符串中所有的匹配项,而search返回的仅仅是第一个匹配项。match更为严格,
它只在字符串的起始位置进行匹配。作为一个不重要的示例,我们考虑下一段文本以及一个可以识别大部分电子邮件地址的正则表达式:'''
text = """Dave [email protected]
Steve [email protected]
Rob [email protected]
Ryan [email protected]"""
pattern = r'[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}'
#re.IGNORECASE使正则表达式不区分大小写
# regex = re.compile(pattern, flags=re.IGNORECASE)
# print(regex.findall(text)) #['[email protected]', '[email protected]', '[email protected]', '[email protected]']

'''search返回的是文本中第一个匹配到的电子邮件地址。对于前面提到的正则表达式,匹配对象只能告诉我们模式在字符串中起始和结束的位置:'''
# m = regex.search(text)
# print(m) #<_sre.SRE_Match object; span=(5, 20), match='[email protected]'>
# print(text[m.start():m.end()]) #[email protected]

'''regex.match只在模式出现于字符串起始位置时进行匹配,如果没有匹配到,返回None:'''
# print(regex.match(text)) #None

'''相关地,sub会返回一个新的字符串,原字符串中的模式会被一个新的字符串替代:'''
# print(regex.sub('REDACTED', text))
'''
Dave REDACTED
Steve REDACTED
Rob REDACTED
Ryan REDACTED'''

'''假设你想查找电子邮件地址,并将每个地址分为三个部分:用户名,域名和域名后缀。要实现这一点,可以用括号将模式包起来:'''
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
regex = re.compile(pattern, flags=re.IGNORECASE)
'''由这个修改后的正则表达式产生的匹配对象的groups方法,返回的是模式组件的元组:'''
m = regex.match('[email protected]')
# print(m.groups()) #('wesm', 'bright', 'net')

'''当模式可以分组时,findall返回的是包含元组的列表:'''
# print(regex.findall(text))
#[('dave', 'google', 'com'), ('steve', 'gmail', 'com'), ('rob', 'gmail', 'com'), ('ryan', 'yahoo', 'com')]

'''sub也可以使用特殊符号,如\1和\2,访问每个匹配对象中的分组。符号\1代表的是第一个匹配分组,\2代表的是第二个匹配分组,以此类推:'''
# print(regex.sub(r'Username: \1, Domain: \2, Suffix: \3', text))
'''
Dave Username: dave, Domain: google, Suffix: com
Steve Username: steve, Domain: gmail, Suffix: com
Rob Username: rob, Domain: gmail, Suffix: com
Ryan Username: ryan, Domain: yahoo, Suffix: com'''

'''
表:正则表达式方法
方法          描述
findall     将字符串中所有的非重叠匹配模式以列表形式返回
finditer    与findall类似,但返回的是迭代器
match       在字符串起始位置匹配模式,也可以将模式组建匹配到分组中;如果模式匹配上了,返回匹配对象,否则返回None
search      扫描字符串的匹配模式,如果扫描到了返回匹配对象,与match方法不同的是,search方法的匹配可以是字符串的任意位置,而不仅仅是字符串的起始位置
split       根据模式,将字符串拆分为多个部分
sub, subn   用替换表达式替换字符串中所有的匹配(sub)或第n个出现的匹配串(subn),使用符号\1、\2.....来引用替换字符串中的匹配组元素
'''

'''
常用的匹配规则
模式      描述
\w      匹配字母、数字及下划线
\W      匹配不是字母、数字及下划线的字符
\s      匹配任意空白字符,等价于[\t\n\r\f]
\S      匹配任意非空字符
\d      匹配任意数字,等价于[0-9]
\D      匹配任意非数字的字符
\A      匹配字符串开头
\Z      匹配字符串结尾,如果存在换行,只匹配到换行前的结束字符串
\z      匹配字符串结尾,如果存在换行,同时还会匹配换行符
\G      匹配最后匹配完成的位置
\n      匹配一个换行符
\t      匹配一个制表符
^       匹配一行字符串的开头
$       匹配一行字符串的结尾
.       匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
[...]   用来表示一组字符,单独列出,比如[amk]匹配a、m或k
[^...]  不在[]中的字符,比如[^abc]匹配除了a、b、c之外的字符
*       匹配0个或多个表达式
+       匹配1个或多个表达式
?       匹配0个或1个前面的正则表达式定义的片段,非贪婪方式
{n}     精确匹配n个前面的表达式
{n, m}  匹配n到m次由前面正则表达式定义的片段,贪婪方式
a|b     匹配a或b
()      匹配括号内的表达式,也表示一个组
'''

'''5.3.3 pandas中的向量化字符串函数'''
data = {'Dave':'[email protected]', 'Steve':'[email protected]', 'Rob': '[email protected]', 'Wes': np.nan}
data = pd.Series(data)
'''你可以使用data.map将字符串和有效的正则表达式方法(以lambda或其他函数的方式传递)应用到每个值上,但是在NA(null)值上会失败。
为了解决这个问题,Series有面向数组的方法用于跳过NA值的字符串操作。这些方法通过Series的str属性进行调用。
例如,可以通过str.contains来检查每个电子邮件地址是否含有“gmail”:'''
# print(data.str.contains('gmail'))
'''
Dave     False
Steve     True
Rob       True
Wes        NaN
dtype: object'''

'''正则表达式也可以结合任意的re模块选项使用,例如IGNORECASE:'''
pattern = r'([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\.([A-Z]{2,4})'
# print(data.str.findall(pattern, flags=re.IGNORECASE))
'''
Dave     [(dave, google, com)]
Steve    [(steve, gmail, com)]
Rob        [(rob, gmail, com)]
Wes                        NaN
dtype: object'''

'''有多种方法可以进行向量化的元素检索。可以使用str.get或在str属性内部索引:'''
matches = data.str.match(pattern, flags=re.IGNORECASE)
# print(matches)
'''
Dave     True
Steve    True
Rob      True
Wes       NaN
dtype: object'''

'''要访问嵌入式列表中的元素,我们可以将索引传递给这些函数中的任意一个:'''
# print(matches.str.get(1))
# print(matches.str[0])

'''可以使用字符串切片的类似语法进行向量化切片:'''
# print(data.str[:5])
'''
Dave     dave@
Steve    steve
Rob      rob@g
Wes        NaN
dtype: object'''

'''
表:部分向量化字符串方法列表
方法          描述
cat         根据可选的分隔符按元素黏合字符串
contains    返回是否含有某个模式/正则表达式的布尔值数组
count       模式出现次数的计数
extract     使用正则表达式从字符串Series中分组抽取一个或多个字符串;返回的结果是每个分组形成一列的DataFrame
endswith    等价于对每个元素使用x.endwith(模式)
startswith  等价于对每个元素使用x.startwith(模式)
findall     找出字符串中所有的模式/正则表达式匹配项,以列表返回
get         对每个元素进行索引(获得第i个元素)
isalnum     检测字符串是否由字母和数字组成
isalpha     检测字符串是否只由字母组成
islower     检测字符串是否由小写字母组成
isupper     检测字符串是否由大写字母组成
join        根据传递的分隔符,将Series中的字符串联合
len         计算每个字符串的长度
lower,upper 转换大小写;等价于对每个元素进行x.lower()或x.upper()
match       使用re.match将正则表达式应用到每个元素上,将匹配分组以列表形式返回
pad         将空白加到字符串的左边、右边或两边
center      等价于pad(side='both')
repeat      重复值(例如s.str.repeat(3)等价于对每个字符串进行x*3)
replace     以其他字符串替代模式/正则表达式的匹配项
slice       对Series中的字符串进行切片
split       以分隔符或正则表达式对字符串进行拆分
strip       对字符串两侧的空白进行消除,包括换行符
rstrip      消除字符串右边的空白
lstrip      消除字符串左边的空白

isdecimal   检查字符串是否只包含十进制字符。这种方法只存在于unicode对象(定义一个十进制字符串,只需要在字符串前添加 'u' 前缀即可)
isdigit     检测字符串是否只由数字组成
isnumeric   检测字符串是否只由数字组成,这种方法是只针对unicode对象
三者的区别:
isdigit()
True: Unicode数字,byte数字(单字节),全角数字(双字节),罗马数字
False: 汉字数字
Error: 无

isdecimal()
True: Unicode数字,全角数字(双字节)
False: 罗马数字,汉字数字
Error: byte数字(单字节)

isnumeric()
True: Unicode数字,全角数字(双字节),罗马数字,汉字数字
False: 无
Error: byte数字(单字节)
'''

你可能感兴趣的:(Pandas)