【python字符串】基础知识补课

2018.04.15 已经用python一段时间了,最近遇到几个与字符串相关的问题,虽然最后都解决了,但很不pythonic,所以决定回补字符串相关基础知识。

参考资料:

python3中文版参考-第二章:字符串和文本
小甲鱼 字符串:格式化 – 零基础入门学习Python015

先看基础——正则表达

参考:python正则表达式系列(1)——正则元字符
why?因为字符串的处理除了用到python的str方法之外,很多时候还需要用到re正则模块中更加强大、灵活的方法进行处理,而后者的重要基础就是正则。因此,想要灵活处理字符串问题,就必须先掌握正则基础。
正则元字符:. ^ $ * + ? { } [ ] \ | ( )

A 元字符之[ ]——指定字符集
正则表达式[]里的五个特殊字符
通常的字符集匹配:

  • [abc]匹配:a或b或c
  • [^a]匹配:匹配非a的一个字符;
  • [a-zA-Z0-9]匹配:大小写英文字母和数字
  • [^0-9]匹配:不包含0123456789的其他任意字符

然而,
① [ ] - \ ^五个字符在[ ]中都有着特殊意义,而其余的元字符.、*、+、|在[ ]中均不再保留任何特殊意义;
②因此,若要在[]中匹配[ ]-\^五个元字符一定要添加反义字符 \

  • [\^a\-bc]匹配:^和a和-和b和c共五个字符组成的字符集
  • [a+]匹配:a或+
  • [*\-+]匹配:* - + 推荐!
  • [*-+]这个表达式其实表示的是*的ASCII值到+的ASCII值的范围。不推荐!
  • [+-*]将会报错,就像你不能写成[9-0]一样,因为+、*的ASCII值大小顺序反了。错误!

B 元字符之()——匹配 pattern 并保留匹配符号
正则表达式 - 元字符
(pattern): 匹配 pattern 并获取这一匹配;
(?:pattern): 匹配 pattern 但不获取匹配结果;
(?=pattern):正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
(?!pattern):正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
(?<=pattern):反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。
(?

C 元字符之{ }——匹配前一个字符或子表达式出现指定次数
例如:

  • {0,}:0次或多次,相当于*
  • {1,}:1次或多次,相当于+
  • {0,1}:0次或1次,相当于?
  • {m,n}:m次到n次(m <= n)

1 字符串分割:str.split()和re.split()

参考:
Python字符串分割方法总结
中文说明 2.1 使用多个界定符分割字符串

1.1 str.split()方法

S.split(sep=None, maxsplit=-1) 

返回的是一个list

  • sep为分隔符,默认以空白字符whitespace (空格,TAB和回车)为分隔符;
  • maxsplit为最大分割次数,当指定最大分割次数maxsplit时,结果列表长度为maxsplit+1。;
  • print(str.split._ doc _)查看相关说明
  • 缺点:sep只能指定一个分隔符!!

1.2 re.split()方法

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

返回的是一个list

  • pattern相当于sep的功能,但它是更加灵活的正则表达式;
  • string为目标字符串;
  • maxsplit为最大分割次数,当指定最大分割次数maxsplit时,结果列表长度为maxsplit+1;
  • flags为标志,表示正则表达式用到的标志。
    核心:可以用灵活的正则表达式作为分隔符
    ①用[ ]符号:表示字符集,无需再用或,也不加逗号。
import re
line = 'asdf fjdk; afed, fjek,asdf, foo'
re.split(r'[,;\s]\s*', line)

Out[5]: ['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

②用()符号:保留分割符号

line = 'asdf fjdk; afed, fjek,asdf, foo'
fields = re.split(r'(;|,|\s)\s*', line)

Out[6]: ['asdf', ' ', 'fjdk', ';', 'afed', ',', 'fjek', ',', 'asdf', ',', 'foo']

2. 字符串开头、结尾匹配:str.startwith()、str.endwith()

经常用于文件名、扩展名的快速优雅匹配

>>> filename = 'spam.txt'
>>> filename.endswith('.txt')
True
>>> filename.startswith('file:')
False

返回的是True、False,经常用作if 的判断参数,将if嵌入for循环中进行列表快速筛选!
经典用法1:快速筛选有效数据生成list

>>> filenames
[ 'Makefile', 'foo.c', 'bar.py', 'spam.c', 'spam.h' ]
>>> [name for name in filenames if name.endswith(('.c', '.h')) ]
['foo.c', 'spam.c', 'spam.h'

经典用法2:检查某个文件夹中是否存在指定的文件类型

if any(name.endswith(('.c', '.h')) for name in listdir(dirname)):
  

str.startwith()、str.endwith()的功能用切片比对的方法也能实现,但那样很不优雅!

3.用通配符匹配字符串:fnmatch() 和 fnmatchcase()

与前述的str.startwith()、str.endwith()是字符串精准匹配,而fnmatch() 和 fnmatchcase()可以用通配符进行更加灵活的匹配

from fnmatch import fnmatch, fnmatchcase
#导入fnmatch模块的相关方法
fnmatch('foo.txt', '*.txt')

经典用法:

import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '505996-*-2017.txt'):
        print(file)

4.字符串匹配和搜索:str.find() , str.endswith() , str.startswith()和re.match()

str.find():返回的是字符串在str中第一次出现的位置(int)

text = 'yeah, but no, but yeah, but no, but yeah'
text.find('no')  #返回的是字符串在str中第一次出现的位置(int)
10

re.match():

text1 = '11/27/2012'
if re.match(r'\d+/\d+/\d+', text1):
print('yes')

5.字符串中插入变量:{}和format()方法

参考:2.15 字符串中插入变量

>>> s = '{name} has {n} messages.'
#用{ }来定义变量
>>> s.format(name='Guido', n=37)
#用str.format(变量=vlaue)来给字符串中的变量赋值
out: 'Guido has 37 messages.'

应用场景:爬虫中多页的url地址,切换{num}url中的页码变量

你可能感兴趣的:(【python字符串】基础知识补课)