正则表达式(基础知识)
作用:帮助检查一个字符串是否与某种模式匹配。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
1.匹配规则:
对于单个字符的匹配,\d
匹配一个数字;\w
匹配一个字母或数字;.
可以匹配任意字符;\s
匹配一个空格(包括tab等空白符)。
对于匹配变长的字符,*
表示任意长度的字符(包括0);+
表示至少一个字符;?
表示0个或1个字符;{n}
表示n个字符;{n,m}
表示n~m个字符。例如:\d3\-\d{3,8}
表示可以匹配像’025-1234567’这样任意带区号的号码(解释,其中’-'前的斜杠是因为它需要转义)。
更精细地,[]
表示范围,如:[0-9a-zA-Z\_]
可以匹配一个数字、字母或者下划线;[0-9a-zA-Z\_][0-9a-zA-Z\_]{0,19}
可以匹配由一个数字,字母或下划线开头,后接0~19由一个数字、字母或者下划线组成的字符串。
A|B
可以匹配A或B,所以(P|p)ython
可以匹配’Python’或’python’。^
表示行的开头,^\d
表示必须以数字开头。$
表示行的结束,\d$
表示必须以数字结束。
2.Python的re模块使用:
re.match()
方法判断是否匹配,如果匹配成功,返回一个Match对象,否则返回None。
切分字符串,re.split()
可以将不规则的字符串切分成正确的列表。
>>>str1 ='a b c'
>>>str1.split() #无法识别连续的空格
['a','b','','','c']
>>>import re
>>>re.split(r'\s+',str1)
['a','b','c']
>>>re.split(r'[\s\,]+','a, b c')
['a','b','c']
分组,正则表达式中定义了组的概念,在Match对象上用group()方法可以将字符串的子串提取出来。
>>>import re
>>>m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>>m.groups()
('010','12345')
>>>m.group(0)
'010-12345'
>>>m.group(1)
'010'
>>>m.group(2)
'12345'
编译,当一个正则表达式要重复使用几千次时,可以先对正则表达式进行预编译。
>>> import re
>>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$') #编译
>>> re_telephone.match('010-12345').groups()
('010', '12345')
>>> re_telephone.match('010-8086').groups()
('010', '8086')
知识扩展
1.机器编码:
ASCII编码(127个字符,包括字母,数字和一些符号)是1个字节;Unicode编码(包括所有语言)通常是2个字节;UTF8编码是可变长的(为了节省空间),常用的英文字母被编码成1个字节,汉字通常是3个字节,很生僻的字符才会被编码成4-6个字节。
所以,现在计算机系统通用的字符编码工作方式是:在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器。
对于单个字符的编码,Python提供了ord()
函数获取字符的整数表示,chr()
函数把编码转换为对应的字符。例如:
>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'
2.判断句 if x:
代表的是如果x不是非零数值、非空字符串、非空list等,就判断为True
。
3.输入x = input('input_string:')
,返回的x是个字符串str,即使输入的是数字。
判断输入是否为数字if x.isdigit()
,返回True
就代表输入位数字。同样的还有isalnum()
所有字符都是数字或者字母;isalpha()
所有字符都是字母;isupper()
都是大写;islower
都是小写;istitle()
所有单词首字母都是大写;isspace()
所有字符都是空白字符\t,\r,\n
等。
4.可变对象和不可变对象的本质区别:对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
>>>a = 'abc'
>>>a.replace('a','A') #a变量指向的对象本身不会改变
'Abc'
>>>a
'abc'
>>>b = a.replace('a','A') #新创建一个对象并返回
>>>b
'Abc'
5.函数中默认参数必须指向不变对象,否则默认参数会随着指向对象的改变而变化的。
>>>def add_end(L=[])
>>> L.append('end')
>>> return L
>>>add_end()
['end']
>>>add_end()
['end','end']
函数还可以定义可变参数,即在参数前加*,表示输入参数个数可以是任意个,既可以是0个,也可以是n个。
>>>def calc(*numbers):
>>> sum = 0
>>> for n in numbers:
>>> sum = sum + n * n
>>> return sum
>>>calc()
0
>>>calc(1,2)
3
>>>calc([1,2,3,4])
10
此外,还可以定义关键字参数(即在参数前加**)允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
>>>def person(name, age, **kw):
>>> print('name:', name, 'age:', age, 'other:', kw)
>>>person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
可以通过命名关键词参数来限制关键词参数的名字。def person(name, age, *, city, job)
表示其他参数只接收city
和job
参数。且命名关键字参数必须传入参数名。
6.使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
7.sys
模块中有一个argv
变量,用list存储了命令行的所有参数。argv
至少有一个元素,因为第一个参数永远是该.py文件的名称。运行python3 hello.py
获得的sys.argv
就是[hello.py]
;运行python3 hello.py Machael
获得的sys.argv
就是[hello.py, Machael]
。
8.python文件中if _name_=='_main_'
的意义是当在命令行运行该文件时,会将_name_
置为_main_
;而在其他地方导入该模块(即该文件)时,if判断将失败。因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
9.私有变量和函数,python并没有一种方法限制private函数或变量的访问,但从编程习惯上来讲是不应该引用private函数或变量的。像_xxx
或__xxx
这样的变量或函数就是private的,非公开的。
参考内容: