- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章深入浅析正则表达式re模块(部分)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
正则表达式:
官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑.
什么是正则表达式: 一套规则 - 匹配字符串的 。
谈到正则,就只和字符串相关了。我们要考虑的是在同一个位置上可以出现的字符的范围.
正则表达式能做什么:
•1.检测一个输入的字符串是否合法 -- web开发项目 表单验证 ◦用户输入一个内容的时候,我们要提前做检测 ◦能够提高程序的效率并且减轻服务器的压力 。
•2.从一个大文件中找到所有符合规则的内容 -- 日志分析\爬虫 ◦能够高效的从一大段文字中快速找到符合规则的内容 。
字符组 : [字符组] 。
在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示。一个中括号只表示一个字符位置 字符分为很多类,比如数字、字母、标点等等。假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。 字符组 描述的是一个位置上能出现的所有可能性 # 接受范围,可以描述多个范围,连着写就可以了 # [abc] 一个中括号只表示一个字符位置,匹配a或者b或者c # [0-9] 匹配数字0-9,根据ASCII进行范围的比对 # [a-z] 匹配所有的小写字母 # [A-Z] 匹配所有的大写字母 # [a-zA-Z] 匹配所有的大小写字母 # [0-9a-z] # [0-9a-zA-Z_] 。
元字符:
字符:
元字符 匹配内容的规则 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹配一个制表符 \b 匹配一个单词的结尾 ^ 匹配一个字符串的开始 $ 匹配一个字符串的结尾 \W 匹配非字母或数字或下划线 \D 匹配非数字 \S 匹配非空白符 a|b 匹配字符a或字符b a表达式|b表达式 匹配a或者b表达式中的内容,如果匹配a成功了,不会继续和b匹配, 所以,如果两个规则有重叠部分,总是把长的放在前面 () 分组,匹配括号内的表达式,也表示一个组。约束某一个元字符的作用范围,只在()内生效 [] 字符组,匹配字符组中的字符 [^] 非字符组,匹配除了字符组中字符的所有字符 在正则表达式中能够帮助我们表示匹配的内容的符号都是正则中的 元字符 # [0-9] --> \d 表示匹配一位任意数字 digit # [0-9a-zA-Z_] --> \w 表示匹配数字字母下划线 word # 空格 --> # tab --> \t # enter回车 --> \n # 空格,tab和回车 --> \s 表示所有空白 包括空格 tab和回车 # [\d] \d 表示匹配数字 # [\d\D] [\w\W] [\s\S] 表示匹配所有 # [^\d] 匹配所有的非数字 # [^1] 匹配除数字1以外的所有 # [1-9]\d 匹配两位整数 # [1357]\d 匹配1,3,5,7,开头的两位整数 例1:匹配多个网址: www\.oldboy\.com|www\.baidu\.com|www\.jd\.com|www\.taobao\.com #\.表示取消.的特殊意义 www\.(oldboy|baidu|jd|taobao)\.com #用() 来约束 | 描述的内容的范围 记忆元字符 : 都是表示能匹配哪些内容,一个元字符总是表示一个字符位置上的内容 # \d \w \s \t \n \D \W \S # [] [^] . # ^ $ # | () 。
量词:
量词 用法说明 * 重复0次或更多次,表示0次或多次 {0,} + 重复1次或更多次,表示1次或多次 {1,} ? 重复0次或1次,表示匹配0次或1次 {0,1} {n} 重复n次,表示匹配n次 {n,} 重复n次或更多次,表示匹配至少n次 {n,m} 重复n到m次,表示至少匹配n次,至多m次 例: 匹配整数 \d+ 匹配小数 \d+\.\d+ 匹配整数或小数 : \d+\.?\d* #存在问题,比如1.也会被匹配到 ---> 分组的作用 : \d+(\.\d+)? 例:匹配手机号码,手机号以1开头,第二位为3-9,总共11位 1[3-9]\d{9} 。
#判断用户输入的内容是否合法,如果用户输入的对就能查到结果,如果输入的不对就不能查到结果 ^1[3-9]\d{9}$ # 从一个大文件中找到所有符合规则的内容 1[3-9]\d{9} 。
转义符:
原本有特殊意义的字符,到了表达它本身的意义的时候,需要转义。 。
. 有特殊的意义,取消特殊的意义\. 。
有一些有特殊意义的内容,放在字符组中,会取消它的特殊意义 #只表示符号本身 [().*+?] 所有的内容在字符组中会取消它的特殊意义 #表示:a-c (a减c) [a\-c] -在字符组中表示范围,如果不希望它表示范围,需要转义,或者放在字符组的最前面\最后面 。 取消一个元字符的特殊意义有两种方法: 1. 在这个元字符前面加\ 2. 对一部分字符生效,把这个元字符放在字符组里 # [.()+?*] 。
贪婪匹配:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
1.贪婪匹配:在量词范围允许的情况下,尽量多的匹配内容
.*x 表示匹配任意字符 任意多次数 遇到最后一个x才停下来
回溯算法:
2.非贪婪(惰性)匹配: 总是在量词范围内尽量少的匹配内容。前面的*,+等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
.*?x 表示匹配任意字符 任意多次数 但是一旦遇到x就停下来
.+?x 匹配任意内容至少1次 遇到x就停止
元字符+量词+? ---> 惰性匹配
几个常用的非贪婪匹配:
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
例:匹配身份证号码:18
/15
位的身份证号
# 15位:首位数字为1-9,总共15位
[1-9]\d{14}
# 18位:首位数字为1-9,末位为0-9或者X,总共18位
[1-9]\d{16}[\dx]
[1-9]\d{16}[0-9x]
#1:
[1-9]\d{16}[0-9x]|[1-9]\d{14}
#从一个大文件中找到所有符合规则的内容。表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$
#检测一个输入的字符串是否合法
#2:简化
[1-9]\d{14}(\d{2}[\dx])?
#从一个大文件中找到所有符合规则的内容
^[1-9]\d{14}(\d{2}[\dx])?$
#检测一个输入的字符串是否合法 。()表示分组,将\d{2}[\dx]分成一组,就可以整体约束他们出现的次数为0-1次
例:
规则:1\d*?3 待匹配内容:1243333344 匹配结果:1243
规则:1\d*3 待匹配内容:1243333344 匹配结果:12433333
re模块:
# findall 还是按照完整的正则进行匹配,只是显示括号里匹配到的内容。 取所有符合条件的,优先显示分组中的。
ret = re.findall(
'9\d\d'
,
'19740ash93010uru'
)
print(ret)
#['974', '930']
ret = re.findall(
'9(\d)\d'
,
'19740ash93010uru'
)
print(ret)
#['7', '3']
# search 还是按照完整的正则进行匹配,显示也显示匹配到的第一个内容,但是我们可以通过给group方法传参数,来获取具体分组,即()中的内容。
search 只取第一个符合条件的,没有优先显示这件事儿
得到的结果是一个变量
变量.group() 的结果 完全和 变量.group(0)的结果一致
变量.group(n) 的形式来指定获取第n个分组中匹配到的内容
ret = re.search(
'9(\d)(\d)'
,
'19740ash93010uru'
)
print(ret)
# 变量 <_sre.SRE_Match object; span=(1, 4), match='974'>
if
ret:
print(ret.group())
#974 #ret.group(0) 0 默认不写
print(ret.group(1))
#7
print(ret.group(2))
#4
# 为什么在search中不需要分组优先 而在findall中需要?
加上括号是为了对真正需要的内容进行提取。 为什么要用分组? 把想要的内容放分组里
如果我们要查找的内容在一个复杂的环境中,我们要查的内容并没有一个突出的 与众不同的特点 甚至会和不需要的杂乱的数据混合在一起,这个时候我们就需要把所有的数据都统计出来,然后对这个数据进行筛选,把我们真正需要的数据对应的正则表达式用()圈起来,这样我们就可以筛选出真正需要的数据了。
# 如何取消分组优先
如果在写正则的时候由于不得已的原因,导致不要的内容也得写在分组里,通过 ?: 取消这个分组的优先显示
# (?:) 取消这个分组的优先显示
#findall
ret = re.findall(
'<\w+>(\w+)</\w+>'
,
'<h1>askh930s02391j192agsj</h1>'
)
print(ret)
#['askh930s02391j192agsj']
# search
ret = re.search(
'<(\w+)>(\w+)</\w+>'
,
'<h1>askh930s02391j192agsj</h1>'
)
print(ret.group())
#<h1>askh930s02391j192agsj</h1>
print(ret.group(1))
#h1
print(ret.group(2))
#askh930s02391j192agsj
#从exp中匹配出第一个加法,第一个减法, a+b 或者是a-b 并且计算他们的结果
exp =
'2-3*(5+6)'
ret = re.search(
'(\d+)[+](\d+)'
,exp)
print(ret)
print(ret.group(1))
#5
print(ret.group(2))
#6
print(int(ret.group(1)) + int(ret.group(2)))
#11
#将豆瓣源码放到douban.html,从中获取电影名:
with
open
(
'douban.html'
,encoding=
'utf-8'
) as f:
content = f.
read
()
ret = re.findall(
'<span class="title">(.*?)</span>(?:\s*<span class="title">.*?</span>)?'
,content)
print(ret)
#除了 霸王别姬,其他电影都是 肖申克的救赎 这种格式的。
(.*?) 要显示的电影名 其中 ?是非贪婪匹配的标志
(?:\s*<span class=
"title"
>.*?<
/span
>)?
?: 取消这个分组的优先显示,整个()内都不显示 \s* 两行代码之间所有的空字符
.*? 电影英文名 ? 该部分出现0次 或者1次
# 什么是爬虫
# 通过代码获取到一个网页的源码,需要的是源码中嵌着的网页上的内容 -- 正则表达式
#先安装扩展模块 File--Settings--Project Interpreter-- + --找到包---Install Package
import
requests
ret = requests.get(
'https://movie.douban.com/top250?start=0&filter='
)
print(ret.content.decode(
'utf-8'
))
|
总结 。
以上所述是小编给大家介绍的深入浅析正则表达式re模块(部分),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢! 。
原文链接:https://www.cnblogs.com/xiaomage666/archive/2019/05/27/10934179.html 。
最后此篇关于深入浅析正则表达式re模块(部分)的文章就讲到这里了,如果你想了解更多关于深入浅析正则表达式re模块(部分)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在用 yacc/bison 编写一个简单的计算器。 表达式的语法看起来有点像这样: expr : NUM | expr '+' expr { $$ = $1 + $3; } | expr '-'
我开始学习 lambda 表达式,并在以下情况下遇到了以下语句: interface MyNumber { double getValue(); } MyNumber number; nu
这两个 Linq 查询有什么区别: var result = ResultLists().Where( c=> c.code == "abc").FirstOrDefault(); // vs. va
如果我们查看 draft C++ standard 5.1.2 Lambda 表达式 段 2 说(强调我的 future ): The evaluation of a lambda-expressio
我使用的是 Mule 4.2.2 运行时、studio 7.5.1 和 Oracle JDK 1.8.0_251。 我在 java 代码中使用 Lambda 表达式,该表达式由 java Invoke
我是 XPath 的新手。我有网页的html源 http://london.craigslist.co.uk/com/1233708939.html 现在我想从上面的页面中提取以下数据 完整日期 电子
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我将如何编写一个 Cron 表达式以在每天上午 8 点和下午 3:30 触发?我了解如何创建每天触发一次的表达式,而不是在多个设定时间触发。提前致谢 最佳答案 你应该只使用两行。 0 8 * * *
这个问题已经有答案了: What do 3 dots next to a parameter type mean in Java? (9 个回答) varargs and the '...' argu
我是 python 新手,在阅读 BeautifulSoup 教程时,我不明白这个表达式“[x for x in titles if x.findChildren()][:-1]”我不明白?你能解释一
(?:) 这是一个有效的 ruby 正则表达式,谁能告诉我它是什么意思? 谢谢 最佳答案 正如其他人所说,它被用作正则表达式的非捕获语法,但是,它也是正则表达式之外的有效 ruby 语法。 在
这个问题在这里已经有了答案: Why does ++[[]][+[]]+[+[]] return the string "10"? (10 个答案) 关闭 8 年前。 谁能帮我处理这个 JavaSc
这个问题在这里已经有了答案: What is the "-->" operator in C++? (29 个答案) Java: Prefix/postfix of increment/decrem
这个问题在这里已经有了答案: List comprehension vs. lambda + filter (16 个答案) 关闭 10 个月前。 我不确定我是否需要 lambda 或其他东西。但是,
C 中的 assert() 函数工作原理对我来说就像一片黑暗的森林。根据这里的答案https://stackoverflow.com/a/1571360 ,您可以使用以下构造将自定义消息输出到您的断言
在this页,John Barnes 写道: If the conditional expression is the argument of a type conversion then effec
我必须创建一个调度程序,它必须每周从第一天上午 9 点到第二天晚上 11 点 59 分运行 2 天(星期四和星期五)。为此,我需要提供一个 cron 表达式。 0-0 0-0 9-23 ? * THU
我正在尝试编写一个 Linq 表达式来检查派生类中的属性,但该列表由来自基类的成员组成。下面的示例代码。以“var list”开头的 Process 方法的第二行无法编译,但我不确定应该使用什么语法来
此 sed 表达式将输入字符串转换为两行输出字符串。两条输出行中的每一行都由输入的子串组成。第一行需要转换成大写: s:random_stuff\(choice1\|choice2\){\([^}]*
我正在使用 Quartz.Net 在我的应用程序中安排我的工作。我只是想知道是否可以为以下场景构建 CRON 表达式: Every second between 2:15AM and 5:20AM 最
我是一名优秀的程序员,十分优秀!