python使用正则表达式

一、使用正则表达式步骤

1、寻找规律;

2、使用正则符号表示规律;

3、提取信息,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。

 

二、正则表达式中常见的基本符号

1.点号“.”

    一个点号可以代替除了换行符(\n)以外的任何一个字符,包括但不限于英文字母、数字、汉字、英文标点符号和中文标点符号。

2.星号“*”

    一个星号可以表示它前面的一个子表达式(普通字符、另一个或几个正则表达式符号)0次到无限次。

3.问号“?”

    问号表示它前面的子表达式0次或者1次。注意,这里的问号是英文问号。

4.反斜杠“\”

    反斜杠在正则表达式里面不能单独使用,甚至在整个Python里都不能单独使用。反斜杠需要和其他的字符配合使用来把特殊符号变成普通符号,把普通符号变成特殊符号。如:“\n”。

5.数字“\d”

    正则表达式里面使用“\d”来表示一位数字。再次强调一下,“\d”虽然是由反斜杠和字母d构成的,但是要把“\d”看成一个正则表达式符号整体。

6.小括号“()”

小括号可以把括号里面的内容提取出来。

在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块来操作,名字为re

import re

三、匹配的基本方法

在re模块中,通常使用三种方法,match,search和findall,下面对这三种方法进行简单的介绍:

1.match方法

re.match 尝试从字符串的起始位置匹配一个模式,匹配成功则返回的是一个匹配对象(这个对象包含了我们匹配的信息),如果不是起始位置匹配成功的话,match()返回的是空,
注意:match只能匹配到一个**

下面来看代码理解

s = 'python123python666python888'

result = re.match('python',s)
print(result)  # <re.Match object; span=(0,6),match='python'>
print(result.span())  # (0,6)
print(result.group())  # python

1.通过span()提取匹配到的字符下标
2.通过group()提取匹配到的内容
而s字符串中有3个python的存在,match只能匹配到一个

下面我们改变一下s,得到不一样的结果

s = '1python123python666python888'

result = re.match('python',s)
print(result)  #None

因为match从字符串的起始位置开始匹配,这里起始的第一个字符为1,所以匹配失败返回None.
那么我们要如何才能匹配到字符串中间我们想要的部分呢,这个时候就用到了search函数

2.search方法

re.search 扫描整个字符串,匹配成功则返回的是一个匹配对象(这个对象包含了我们匹配的信息)
注意:search也只能匹配到一个,找到符合规则的就返回,不会一直往后找
同样的,search也只能匹配到一个.
代码如下

s = '1python123python666python888'

result = re.search('python',s)
print(result)  # <re.Match object; span=(1,7),match='python'>
print(result.span())  # (1,7)
print(result.group())  # python

当然,若是都找不到则返回None值

s = '1python123python666python888'

result = re.search('python98',s)
print(result)  # None

*search方法虽然解决了match的从头匹配的弊端,但它也只能匹配到一个,这个时候我们就可以使用findall方法了 *

3.findall方法:

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表

s = '1python123python666python888'

result = re.findall('python',s)
print(result)  # ['python','python','python']

上面的三种方法看上去只能匹配到简单的字符串,也许我们觉得用一般的方法也可以办到:
比如字符串的index方法(也可以用循序)

print(s.index('python'))  # 1
print(s.index('python',2))  # 10
print(s.index('python',11))  # 19

那么正则表达式应该用在什么地方呢:

  • 判断用户注册帐号是否满足格式
  • 抓取页面中特定部分数据
  • 判断用户提交的邮箱的格式是否正确 等等等等
    那么我们就要了解元字符

 

四、元字符匹配规则

元字符:本身具有特殊含义的字符
先看几张常用的图片

单字符匹配: 如下

代表数量的元字符

表示边界的元字符

分组匹配

举例

下面我们来举一些例子

1.匹配账号:只能由字母和数字组成,长度为10位

import re

s = '1587022xzq'

result = re.match('[0-9a-zA-z]{10}',10),match='1587022xzq'>

因为账号是从头到尾的,只需要匹配一次就行,所以我们可以使用match方法,但是上面的代码明显存在问题,比如将长度增加三位,它将依然能匹配到

s = '1587022xzqty'

result = re.match('[0-9a-zA-z]{10}',match='1587022xzq'>

这是因为我们没有加上控制边界的元字符,下面是修改后正确的代码

s = '1587022xzqty'
result = re.match('^[0-9a-zA-z]{10}$',s)
print(result)  # None

解析:

  • (因为对于match来说,从头开始匹配,所以这里的^可以不加)
  • $的意思是匹配到字符串的结尾,
  • 账号的长度为10位是通过代表数量的元字符{10}来控制的

2.匹配qq号:长度为5-11位,纯数字组成,第一位不为0

s = '10086111222'
# 5 - 11 位
result = re.match('[1-9][0-9]{4,10}$',11),match='10086111222'>

解析:

  • 这里的代表数量的元字符{4,10}表示[0-9]出现的次数为[4,9]次(大于等于4,小于等于9),而第一位[0-9]占了一位数字,所以加起来是5-11位符合要求的qq号

我们可以简化一下[0-9]的写法,\d就可以代表纯数字

s = '10086111222'
# 5 - 11 位
result = re.match(r'[1-9]\d{4,match='10086111222'>

tip:这里在字符串前面加上r是为了取消转义,不然就需要写成 \d(虽然这里的\d实际上没有影响)

3.检索文件名 格式为 xxx.py

s = '1.py 2.png ssx.csv qaq.txt xzq.py'
#文件名格式: (数字字母_).py
result = re.findall(r'\w+\.py\b',s)
print(result)	# ['1.py','xzq.py']

解析:

  • \w代表 word,及字母数字或下划线
  • +为控制数量 >=1
  • \b代表边界,这里如果前面不加上r的话\b就应该写成\b
  • 注意点.文件的格式为xxx.py 这里的.需要特别注意,因为在单字符匹配中


    所以我们需要使用 \ . 来表示我们所需要的.

4.匹配1-100的数字

s = '89'

result = re.match(r'[1-9]?\d?$',s)
print(result)	# <re.Match object; span=(0,2),match='89'>

这是第一步的思路,但是当我们把s改为100时就发现了错误

s = '100'

result = re.match(r'[1-9]?\d?$',s)
print(result)  # None

改进之后的代码

s = '100'
r = '98'
z = '9'
q = '0'
result = re.match(r'[1-9]?\d?$|100$',s)
print(result)  
print(re.match(r'[1-9]?\d?$|100$',r))
print(re.match(r'[1-9]?\d?$|100$',z))
print(re.match(r'[1-9]?\d?$|100$',q))
''' <re.Match object; span=(0,3),match='100'> <re.Match object; span=(0,match='98'> <re.Match object; span=(0,1),match='9'> <re.Match object; span=(0,match='0'> '''

5.验证输入的邮箱

# 验证输入的邮箱 163 126 qq 前面至少五位,至多11位
email = '738473800@qq.com'
result = re.match(r'\w{5,11}@(163|126|qq)\.(com|cn)$',email)
print(result)  # <re.Match object; span=(0,16),match='738473800@qq.com'>

注意:括号和方括号的区别
(qq|163|126)代表的是qq或163或126
[qq|163|126]代表的是q1236这几个符号

6.分组提取匹配爬虫电话号码

比如我们用爬虫爬到了一组数据
里面有一组数据是xxxx-xxxxxxxx
前面包含3/4个数字,后面包含8个数字
下面将他们取出,这里我们用到了分组,(小括号)

# 爬虫
phone = '010-12345678'
result = re.match(r'(\d{3}|\d{4})-(\d{8})$',phone)
print(result)  # <re.Match object; span=(0,12),match='010-12345678'>
print(result.group())  # 010-12345678
print(result.group(1))  # 010
print(result.group(2))  # 12345678

一个小括号为一个分组,可以用group提取出来

7.匹配html标签内容

# 爬虫
html标签的格式形如 <xxx>y</xxx>	y为我们要提取的内容
s = '<h1>hello</h1>'
result = re.match('<[0-9A-z]+>(.+)</[0-9A-z]+>$',14),match='<h1>hello</h1>'>
print(result.group(1))  # hello

表面上看这样没什么问题,但如果更改s如下就出现了问题

# 爬虫
s = '<html>hello</h1>'
result = re.match('<[0-9A-z]+>(.+)</[0-9A-z]+>$',match='<html>hello</h1>'>
print(result.group(1))  # hello

所以改进,利用分组来判断

# 爬虫
s = '<html>hello</h1>'
s2 = '<html>hello</html>'
result = re.match(r'<([0-9A-z]+)>(.+)</\1>$',s)
print(result)  # None
result = re.match(r'<([0-9A-z]+)>(.+)</\1>$',s2)
print(result)  # <re.Match object; span=(0,18),match='<html>hello</html>'>
print(result.group(1))  # html
print(result.group(2))  # hello

解析:这里使用\1代表与第一个分组相同
拓展:起名字

# 取名字 (?P<名字>正则) (?P=名字)

看似繁琐了一点,但是在遇到复杂的情况,比如多重标签嵌套,或者其他情况下的时候通过取名分组的方法十分实用,不容易出错

# 取名字 (?P<名字>正则) (?P=名字)
s = '<html>hello</h1>'
s2 = '<html>hello</html>'
result = re.match(r'<(?P<name1>\w+)>(.+)</(?P=name1)>$',s)
print(result)  # None
result = re.match(r'<(?P<name1>\w+)>(?P<msg>.+)</(?P=name1)>$',match='<html>hello</html>'>
print(result.group('name1'))  # html
print(result.group('msg'))  # hello

(3).sub方法

类似于replace替换方法rre.sub(正则表达式,替换成什么,要替换的字符串)

s1 = 'java:90 python:95 html:89'
result = re.sub(r'\d+','90',s1)
print(result)  # java:90 python:90 html:90

不过第二个参数位置可以放函数
比如把取出来的数字都加一,函数可以理解为找到一个匹配的值就执行一次函数

def func(num):
    a = num.group()
    b = int(a) + 1
    return str(b)


s1 = 'java:90 python:95 html:89'
result = re.sub(r'\d+',func,s1)
print(result)  # java:91 python:96 html:90

(4).split方法

split切割,根字符串的spilt类似,但是更加灵活

s1 = 'java:90,python:95,html:89'
result = re.split(r'[,:]',s1)
print(result)  # ['java','95','html','89']

(5).贪婪与非贪婪

正则默认都是用贪婪模式去匹配数据的,就是尽可能多的匹配符合要求的数据
非贪婪模式下,始终找最短匹配


加上?之后就变成非贪婪模式

s1 = 'abc1123avc'
result = re.findall(r'[A-z]+\d+',s1)
print(result)  # ['abc1123']
s1 = 'abc1123avc'
result = re.findall(r'[A-z]+\d+?',s1)
print(result)  # ['abc1']

原文地址:https://blog.csdn.net/a15608445683

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


jquery.validate使用攻略(表单校验) 目录 jquery.validate使用攻略1 第一章&#160;jquery.validate使用攻略1 第二章&#160;jQuery.validate.js API7 Custom selectors7 Utilities8 Validato
/\s+/g和/\s/g的区别 正则表达式/\s+/g和/\s/g,目的均是找出目标字符串中的所有空白字符,但两者到底有什么区别呢? 我们先来看下面一个例子: let name = &#39;ye wen jun&#39;;let ans = name.replace(/\s/g, &#39;&#3
自整理几个jquery.Validate验证正则: 1. 只能输入数字和字母 /^[0-9a-zA-Z]*$/g jQuery.validator.addMethod(&quot;letters&quot;, function (value, element) { return this.optio
this.optional(element)的用法 this.optional(element)是jquery.validator.js表单验证框架中的一个函数,用于表单控件的值不为空时才触发验证。 简单来说,就是当表单控件值为空的时候不会进行表单校验,此函数会返回true,表示校验通过,当表单控件
jQuery.validate 表单动态验证 实际上jQuery.validate提供了动态校验的方法。而动态拼JSON串的方式是不支持动态校验的。牺牲jQuery.validate的性能优化可以实现(jQuery.validate的性能优化见图1.2 jQuery.validate源码 )。 也可
自定义验证之这能输入数字(包括小数 负数 ) &lt;script type=&quot;text/javascript&quot;&gt; function onlyNumber(obj){ //得到第一个字符是否为负号 var t = obj.value.charAt(0); //先把非数字的都
// 引入了外部的验证规则 import { validateAccountNumber } from &quot;@/utils/validate&quot;; validator.js /*是否合法IP地址*/ export function validateIP(rule, value,cal
VUE开发--表单验证(六十三) 一、常用验证方式 vue 中表单字段验证的写法和方式有多种,常用的验证方式有3种: data 中验证 表单内容: &lt;!-- 表单 --&gt; &lt;el-form ref=&quot;rulesForm&quot; :rules=&quot;formRul
正则表达式 座机的: 例子: 座机有效写法: 0316-8418331 (010)-67433539 (010)67433539 010-67433539 (0316)-8418331 (0316)8418331 正则表达式写法 0\d{2,3}-\d{7,8}|\(?0\d{2,3}[)-]?\d
var reg = /^0\.[1-9]{0,2}$/;var linka = 0.1;console.log (reg.test (linka)); 0到1两位小数正则 ^(0\.(0[1-9]|[1-9]{1,2}|[1-9]0)$)|^1$ 不含0、0.0、0.00 // 验证是否是[1-10
input最大长度限制问题 &lt;input type=&quot;text&quot; maxlength=&quot;5&quot; /&gt; //可以 &lt;input type=&quot;number&quot; maxlength=&quot;5&quot; /&gt; //没有效
js输入验证是否为空、是否为null、是否都是空格 目录 1.截头去尾 trim 2.截头去尾 会去掉开始和结束的空格,类似于trim 3.会去掉所有的空格,包括开始,结束,中间 1.截头去尾 trim str=str.trim(); // 强烈推荐 最常用、最实用 or $.trim(str);
正则表达式语法大全 字符串.match(正则):返回符合的字符串,若不满足返回null 字符串.search(正则):返回搜索到的位置,若非一个字符,则返回第一个字母的下标,若不匹配则返回-1 字符串.replace(正则,新的字符串):找到符合正则的内容并替换 正则.test(字符串):在字符串中
正整数正则表达式正数的正则表达式(包括0,小数保留两位): ^((0{1}.\d{1,2})|([1-9]\d.{1}\d{1,2})|([1-9]+\d)|0)$正数的正则表达式(不包括0,小数保留两位): ^((0{1}.\d{1,2})|([1-9]\d.{1}\d{1,2})|([1-9]+
JS 正则验证 test() /*用途:检查输入手机号码是否正确输入:s:字符串返回:如果通过验证返回true,否则返回false /function checkMobile(s){var regu =/[1][3][0-9]{9}$/;var re = new RegExp(regu);if (r
请输入保留两位小数的销售价的正则: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/ 1.只能输入英文 &lt;input type=&quot;text&quot; onkeyup=&quot;value
判断价格的正则表达式 价格的正则表达式 /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/; 1 解析:价格符合两种格式 ^ [1-9]\d*(.\d{1,2})?$ : 1-9 开头,后跟是 0-9,可以跟小数点,但小数点后要带上 1-2 位小数,类似 2,2
文章浏览阅读106次。这篇文章主要介绍了最实用的正则表达式整理,比如校验邮箱的正则,号码相关,数字相关等等,本文给大家列举的比较多,需要的朋友可以参考下。_/^(?:[1-9]d*)$/ 手机号
文章浏览阅读1.2k次。4、匹配中的==、an==、== an9、i9 == "9i"和99p==请注意下面这部分的作用,它在匹配中间内容的时候排除了说明:当html字符串如下时,可以匹配到两处,表示匹配的字符串不包含and且不包含空白字符。说明:在上面的正则表达式中,_gvim正则表达式匹配不包含某个字符串
文章浏览阅读897次。【代码】正则表达式匹配a标签的href。_auto.js 正则匹配herf