正则表达式
正则表达式默认只匹配一个
正则表达式学习
正则表达式(Regex)的开始与结束
//代表正则表达式的开始与结束
/匹配字符/
.默认可以匹配所有字符的所有个

[]默认匹配字符集
[]匹配字符集默认只匹配一个,[]里面可以理解为或者的意思

例如:上图regex的意思是匹配yanyuan1或2或3ooo
[^]否定字符集匹配
这里的否定字符集匹配是否定字符集的并集

例如:上图regex的意思是否定匹配yanyuan1或2或3ooo
[-]字符集里面的范围表示
[a-z]:小写字母范围
[A-Z]:大写字母范围
[0-9]:数字范围
[a-zA-Z0-9]:混合字母数字匹配
[\u4e00-\u9fa5]:中文匹配
[!-.]:!"# $ % & ' ( ) * +, - .一部分特殊字符匹配
[^a-zA-Z0-9\u4e00-\u9fa5]:特殊字符匹配,(换行符也匹配)
*号匹配
*号表示一个字符完全不匹配或可以匹配多次。例如,表示字母 e 在下方文本中不出现,只出现 1 次或者并排出现多次。

+号匹配
+号表示一个字符可以出现一次或多次,我们将 + 放在它后面。例如,表示 e 在下方文本中出现一次或多次。

?号匹配
?号表示一个字符可选,即出现0次或者一次。例如下方regex匹配了abd、abcd

{}匹配
{}表示一个字符出现的确切次数,我们在该字符的末尾,将它出现的次数写进大括号 {} 中,如 {n}。例如,表示下方文本中的字母 e 只能出现 2 次。

{,}至少匹配
{,}表示一个字符至少出现多少次,我们在该字符的末尾,将它至少应出现的次数写进大括号 {} 中,并在数字后面加上逗号 ,即匹配大于等于n,如 {n, }。例如,表示下方文本中的字母 e 至少出现 3 次。

{,}范围匹配
{,}表示一些字符出现的次数在某个数字范围内,我们在该字符的末尾,将它至少和至多出现的次数写进大括号 {} 中,中间用逗号 , 分隔,如 {x,y}。例如,匹配下方文本中,字母 e 出现 1 至 3 次的单词。

()分组匹配
()第一组用 \1 来避免重复书写。这里的 1 表示分组的顺序。请在表达式的末尾键入 \2 以引用第二组。\1表示ha,\2表示haa

(?:)分组不被捕获
(?:)表示这个分组不进行引用
这里有两个分组,第一个分组是ha,第二个分组是haa,但是第一个分组不被捕获(也就是除了他以外的分组)

|匹配
|表示表达式匹配多个数据

例如:上图regex的意思是匹配c或r at或者dog
\转义字符

^行首匹配
和全局匹配/g也无法进行每行匹配

/m多行匹配才能影响^行首匹配

$行尾匹配

特殊字符表义
\w:字母、数字和下划线
\W:非字母、数字、下划线
\d:数字
\D:非数字
\s:空白符
\b:单词边界
特殊字符表义中大写表示排除该表义字符
(?=)正向先行断言
(?=PM)表示选中但是不匹配

(?!)负向先行断言
(?!)表示选中不是括号内的也不进行匹配


正向后行断言: (?<=)

负向后行断言:(?<!)

标志
/g:全局匹配
/m:多行匹配
/i:忽略大小写
贪婪匹配
regex默认执行贪婪匹配

例如:上图.*y这里*号可以表示匹配一个或者多个,但是regex默认匹配多个
懒惰匹配

/g和/m的解释与例子说明
1 2 3 4
| /m 修饰符影响的是 ^ 和 $ 的行为,使它们匹配每一行的 行首 和 行尾,而不是整个文本的开始和结束。 /g 修饰符使正则表达式执行 全局匹配,即匹配所有符合条件的结果,而不是仅匹配第一个。
在正则使用^$后,/m可对每一行的行首行尾执行正则匹配操作,但依然只会匹配一个,添加/m之后可以对每行进行正则匹配
|
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
| /^php$/i
TEXT: php php
Outcome: NULL
因为^表示从字符串开始,$表示到字符串结尾,也就是说它匹配的是整个文本只为php
/^php$/im
TEXT: php php
Outcome: php(第一个)
TEXT: phphp php
Outcome: php(第二个)
/m将上面的所有文本字符串匹配,分隔成每一行的字符串匹配
/^php$/img
TEXT: php php
Outcome: php php
/m先对每一行进行正则匹配操作,/g返回所有成功匹配结果
|
常用的正则表达式
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
| 一、校验数字的表达式 数字:^[0-9]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(0|[1-9][0-9]*)$ 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$ 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$ 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$ 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$ 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$ 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$ 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$ 非负整数:^\d+$ 或 ^[1-9]\d*|0$ 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
二、校验字符的表达式 汉字:^[\u4e00-\u9fa5]{0,}$ 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ 长度为3-20的所有字符:^.{3,20}$ 由26个英文字母组成的字符串:^[A-Za-z]+$ 由26个大写英文字母组成的字符串:^[A-Z]+$ 由26个小写英文字母组成的字符串:^[a-z]+$ 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$ 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$ 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$ 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+ 禁止输入含有~的字符:[^~\x22]+
三、特殊需求表达式 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.? InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7} 身份证号: 15或18位身份证:^\d{15}|\d{18}$ 15位身份证:^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$ 18位身份证:^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$ 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$ 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$ 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$ 日期格式:^\d{4}-\d{1,2}-\d{1,2} 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$ 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$ 中文字符的正则表达式:[\u4e00-\u9fa5] 空白行的正则表达式:\n\s*\r (可以用来删除空白行) HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力) 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式) 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始) 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字) IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
|
python一般使用自带函数进行正则匹配
一般是用re模块
1 2 3 4 5 6
| import re
txt = "Hello, world!" match = re.search("a", txt) print(match)
|
Java也是使用自带函数进行正则匹配
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| \:将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n。\n 匹配换行符。序列 \\\\ 匹配 \\ ,\\( 匹配 (。
^:匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配。
$:匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与"\n"或"\r"之前的位置匹配。
①字符的取值范围
[abc] : 表示可能是a,可能是b,也可能是c。
[^abc]: 表示不是a,b,c中的任意一个
[a-zA-Z]: 表示是英文字母
[0-9]:表示是数字
②字符表示
.:匹配任意的字符,除了换行符。
\d:表示数字
\D:表示非数字
\s:表示由空格组成,[ \t\n\r\x\f]
\S:表示由非空字符组成,[^\s]
\w:表示字母、数字、下划线,[a-zA-Z0-9_]
\W:表示不是由字母、数字、下划线组成
\b:匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。
\B:非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。
③数量表达式
?: 表示出现0次或1次,同下+和*,跟在字母或者.点号后面。
+: 表示出现1次或多次
*: 表示出现0次、1次或多次
{n}:表示出现n次
{n,m}:表示出现n~m次
{n,}:表示出现n次或n次以上 ①校验数字的表达式
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(\.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(\.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非负整数:^\d+$ 或 ^[1-9]\d*|0$
非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
②校验字符的表达式
汉字:^[\u4e00-\u9fa5]{0,}$ //涉及到编码了
英文和数字:^[A-Za-z0-9]+$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+
③真实实例
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
电话号码:^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? /> ( 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
|
习题
一、基础匹配题
题目:使用正则表达式匹配以下文本中的目标内容。
匹配所有数字
- 文本:
"Age: 25, Height: 180cm, Weight: 75kg"
- 目标:
25, 180, 75
/[0-9]+/g或者/\d+/g
匹配所有邮箱地址
- 文本:
"Contact: alice@example.com, bob@gmail.com"
- 目标:
alice@example.com, bob@gmail.com
/\w+@\w+.com/g或者/\w+@\w+(.\w+)+/g
匹配所有以 http:// 或 https:// 开头的 URL
- 文本:
"Links: http://example.com, https://google.com, ftp://server.com"
- 目标:
http://example.com, https://google.com
/https?://\w+.com/g
匹配所有日期(格式:YYYY-MM-DD)
- 文本:
"Dates: 2023-05-20, 1999-12-31, 2024/01/01"
- 目标:
2023-05-20, 1999-12-31
\d{4}-\d{2}-\d{2}
匹配所有 HTML 标签(如 <p>, <div>)
- 文本:
"<p>Hello</p><div>World</div>"
- 目标:
<p>, </p>, <div>, </div>
/<.{1,4}>/g或者/<[^>]+>/g
二、进阶匹配题
题目:使用正则表达式完成更复杂的匹配任务。
匹配所有单词的首字母大写(如 Hello, World)
- 文本:
"Hello World, this is a Test"
- 目标:
Hello, World, Test
/[A-Z]{1,}[a-z]+/g
匹配连续重复的单词(如 the the)
- 文本:
"This is is a test test sentence."
- 目标:
is is, test test
/\b(\w+)\s+\1\b/g
匹配所有 IPv4 地址(如 192.168.1.1)
- 文本:
"IPs: 192.168.1.1, 256.300.400.500, 10.0.0.1"
- 目标:
192.168.1.1, 10.0.0.1
/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/g
匹配所有中文汉字
- 文本:
"你好Hello, 世界World!"
- 目标:
你, 好, 世, 界
/[\u4e00-\u9fa5]/g
匹配所有信用卡号(16位数字,可能带 - 或空格分隔)
文本:"Cards: 1234-5678-9012-3456, 1111 2222 3333 4444, 9999999999999999"
目标:1234-5678-9012-3456, 1111 2222 3333 4444, 9999999999999999
/\d+(-| )?\d+(-| )?\d+(-| )?\d+/g