Python正则表达式(一)

106 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

match和search

简单的正则表达式大家都知道,但是复杂的表达式就不是那么容易了,每天弄懂一部分知识点就够了

今日知识点怎么使用,怎么返回什么

import re

if __name__ == '__main__':
    bt = 'bat|bet|bit'
    m = re.match(bt, 'bet')
    if m is not None:
        result = m.group()
        print(result)

    m = re.match(bt, 'batbet')
    if m is not None:
        result = m.group()
        print(result)

    m = re.match(bt, 'ggbet')
    if m is not None:
        result = m.group()
        print(result)
# 控制台打印出来的结果为:
bet
bat

从上面的信息来看,python的 re 模块中的 match方法这种用法只能匹配出字符串开始是否包含指定的部分,而且只读取返回的结果只有一条数据,不知道大家理解了没有,没有理解可以将上面的代码直接复制运行,当然这句话也不完全对,上面代码如果换成这样的话就说的不对了

    bt = '(bat).(bet).(bit)'
    m = re.match(bt, 'batmbetubit')
    if m is not None:
        result = m.group(3)
        print(result)

接下来一起看下 search

    bt = 'bit'
    m = re.search(bt, 'hfgkfkjbit')
    if m is not None:
        result = m.group()
        print(result)

re中的search这个方法的就可以从一整句中查询是否包含需要的部分,而不仅仅的是查找开头有没有

    a = "123abc456"
    print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0))  # 123abc456,返回整体
    print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1) ) # 123
    print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2)) # abc
    print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(3))  # 456
    print("-"*50)
    m = "(bet)...(bat)"
    result = re.search(m, "betljhbat")
    print(result.group(0))  # 返回整体
    print(result.group(1))  # 返回bet
    print(result.group(2))  # 返回bat

总的来说 match和search的功能绝大部分是相同的,不同的部分在于search是在整体搜索,而match是从开始搜索,其他部分基本相同

上面的例子要注意理解group这个,group是分组的意思,正则里面的小括号表示获取当前的值并返回成元组通过group来获取,一般第一个元素是整体元素也就是整个字符串

检索和替换

简单的对上期的search和match进行一下简单补充,两者最大的区别在于match是从开始部分进行匹配,没有匹配到就返回空,而search是整句扫描进行匹配


好了,开始今天的内容

大家看下这段代码

    patter1 = '#.*$'  # 删除注释的正则表达式
    patter2 = '\D'  # 删除非数字的正则表达式
    source = "15527%051_13-2 #这是电话"
    print(source)
    result = re.sub(patter1, '', source)  # 把注解删掉
    print(result)
    result2 = re.sub(patter2, '', result) # 把非数字的删掉
    print(result2)
# 控制台打印出来的结果为:
#15527%051_13-2 #这是电话
#15527%051_13-2 
#15527051132

分析这个sub方法的参数问题

    '''
    下面有四个参数
    1 pattern 很明显是匹配规则
    2 repl是替换的字符串
    3 string 需要处理的字符串
    4 count是表示匹配后替换的个数,一般是0,表示把匹配到的全部给替换掉,一般不写
    5 这个是标志位,是否忽视大小写等等之类的
    # re.sub(pattern, repl, string, count=0 , flag=None)
    '''
    ```

 在看下下面的代码

```python
    inputStr = "hello python,ni hao c,zai jian python"
    replaceStr = re.sub(r"hello (\w+),ni hao (\w+),zai jian \1", "PHP", inputStr)
    print(replaceStr)

    inputStr = "hello python,ni hao c,zai jian python"
    replaceStr = re.sub(r"hello (\w+),ni hao (\w+),zai jian \2", "PHP", inputStr)
    print(replaceStr)
    #打印结果
    #PHP
	#hello python,ni hao c,zai jian python

为什么会产生这样的结果呢,我们逐一的分析下

  • 用 PHP来代替 hello (\w+),ni hao (\w+),zai jian \1匹配到的内容 ,当然全部匹配到了,所以返回PHP \1 表示取第一个分组匹配到的内容,也就是python这个字符串作为匹配格式,放到\1这个位置进行匹配,python刚好匹配到了python。如果换成\2的话就是,C匹配python,肯定匹配不成功,如果是这样的话就会返回原来的字符串,就如同第二个例子

使用函数来处理匹配

def pythonReSubDemo():

	# 源字符串
    inputStr = "hello 123 world 456"

    def _add111(matched):
	    print("执行----")
        intStr = matched.group("number") #123
        intValue = int(intStr)
        addedValue = intValue + 111 #234
        addedValueStr = str(addedValue)
        return addedValueStr

    replacedStr = re.sub("(?P<number>\d+)", _add111, inputStr)
    print("replacedStr=", replacedStr) #hello 234 world 567
    '''
		(?P<number>\d+)这个是分组,然后在指定一个额外的别名,也就是number 在上面就有获取这个分组
    '''
    # 控制台打印的结果为
    #执行----
	#执行----
	#replacedStr= hello 234 world 567

从上面控制台打印的结果来看,_add111这个方法是执行了两次。 **replacedStr = re.sub("(?P\d+)", _add111, inputStr)**在这个匹配中对匹配的进行分组命名为number 每匹配到一次就执行 _add111这个方法,然后通过分组名来拿到指定的匹配值 return 返回后就进行替换了