首页
About
友情链接
Search
1
RustDesk远程桌面工具自建服务器教程
2,352 阅读
2
V2ray配置文件翻译
1,602 阅读
3
draw.io(diagrams.net) - 免费开源全平台绘图软件
1,229 阅读
4
Android 11 中的软件包可见性
1,134 阅读
5
Windows常用软件
981 阅读
Uncategorized
Software
Android
Linux
Communist Party of China
Docker
Windows
Tools
登录
Search
Leon
累计撰写
36
篇文章
累计收到
52
条评论
首页
栏目
Uncategorized
Software
Android
Linux
Communist Party of China
Docker
Windows
Tools
页面
About
友情链接
搜索到
8
篇与
Linux
的结果
2024-08-16
wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。
https://www.cnblogs.com/LLW-NEU/p/17857553.htmlWSL 中有一个配置文件用于配置高级设置选项,那就是 .wslconfig.这个文件默认是没有的,如果要配置,我们要手动创建。这个文件在 C:Users<UserName>.wslconfig 中。创建文件后,填入以下内容并保存。[experimental] autoMemoryReclaim=gradual # gradual | dropcache | disabled networkingMode=mirrored dnsTunneling=true firewall=true autoProxy=true再打开 power shell,输入 wsl --shutdown,重新打开 WSL,就没有之前的提示了。
2024年08月16日
191 阅读
0 评论
0 点赞
2023-04-08
此内容被密码保护
加密文章,请前往内页查看详情
2023年04月08日
8 阅读
0 评论
0 点赞
2022-09-26
禁用Ubuntu鼠标中键复制功能
禁用Ubuntu鼠标中键复制xmodmap -e "pointer = 1 25 3 4 5 6 7 2"xmodmap命令是在修改按键映射,pointer指鼠标,1 2 3 指鼠标的 “左中右” 三个按键。恢复Ubuntu鼠标中键复制xmodmap -e "pointer = 1 2 3 4 5 6 7 8"原文地址:https://blog.csdn.net/weixin_46201756/article/details/106321704
2022年09月26日
275 阅读
0 评论
1 点赞
2022-07-14
Linux分区与Windows分区冲突时
inode bitmap中有标记为已使用的未用 inode。 文件:1311130sudo find / inum 1311130sudo rm
2022年07月14日
510 阅读
0 评论
0 点赞
2021-10-08
正则表达式
1. 正则表达式1.1 简介正则表达式(英语:Regular Expression,常简写为regex、regexp或RE),又称正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。1.2 用途给定一个正则表达式和另一个字符串,我们可以达到如下的目的:给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”):可以通过正则表达式,从字符串中获取我们想要的特定部分。1.3 特点由于正则表达式主要应用对象是文本,因此它在各种文本编辑器场合都有应用,小到著名编辑器EditPlus,大到Microsoft Word、Visual Studio等大型编辑器,都可以使用正则表达式来处理文本内容。灵活性、逻辑性和功能性非常强。可以迅速地用极简单的方式达到字符串的复杂控制。对于刚接触的人来说,比较晦涩难懂。1.4 基本语法一个正则表达式通常被称为一个模式(pattern),为用来描述或者匹配一系列匹配某个句法规则的字符串。一个正则表达式通常由基本的元字符+限定符构成:例如:Handel、Händel和Haendel这三个字符串,都可以由H(a|ä|ae)ndel这个模式来描述。这个式子的意思是:匹配H一次,a、ä或者ae一次,n一次,d一次,e一次,l一次。1.4.1 元字符元字符描述实例.匹配除换行符以外的任何字符。使用"\."可匹配一个"."如果放在"[]"内也表示匹配一个"."而不是"除换行符以外的任何字符"。 ()将一系列字符组合为一个group,当成功匹配到字符时可分别取出它们。 f匹配一个换页符。等价于 x0c 和 cL。 n匹配一个换行符。等价于 x0a 和 cJ。 r匹配一个回车符。等价于 x0d 和 cM。 [...]当字符括在中括号内时,与在任何别的位置一样,普通字符在中括号内表示其本身,即,它在输入文本中匹配一次其本身。大多数特殊字符在中括号表达式内出现时失去它们的意义。但除外,要匹配 字符,请使用\\。 1匹配"[]"不包含的任意字符。 w匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。 W匹配非字母、数字、下划线。等价于'[ ^A-Za-z0-9_]'。 s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]。 S匹配任何非空白字符。等价于 [ ^fnrtv]。 d匹配一个数字字符。等价于 [0-9]。 D匹配一个非数字字符。等价于 2。 t匹配一个制表符。等价于 x09 和 cI。 v匹配一个垂直制表符。等价于 x0b 和 cK。 1.4.2 限定符字符后面不加匹配次数表示匹配前面的字符仅一次。字符作用?表示匹配前一个元素出现零次或一次。例如,colou?r可以匹配“colour”和“color”。*表示匹配前一个元素出现零次或多次。例如,ab*c可以匹配"ac", "abc", "abbc", "abbbc"等等。+表示匹配前一个元素出现零次或一次(至少一次)。 例如: ab+c可以匹配"abc", "abbc", "abbbc"等等, 但是匹配不到 "ac"。{n}表示匹配前一个元素出现n次。{min,}表示匹配前一个元素出现至少min次。{,max}表示匹配前一个元素出现最多max次。{min,max}表示匹配前一个元素出现至少min次,最多max次。1.4.3 定位符字符描述^匹配输入字符串开始的位置。$匹配输入字符串结尾的位置。b匹配一个单词边界,即字与空格间的位置。'erb' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。B非单词边界匹配。'erB' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。1.4.4 贪婪正则表达式默认匹配模式是贪婪模式(尽量多匹配)如需要非贪婪匹配(最小匹配)可以使用?标记*, +, ? 或{M,N}为非贪婪匹配模式。如:使用(l.+?o)匹配"Hello World":如果+后不加?表示这个+是贪婪的,那么匹配结果就是"llo Wo"。如果加了?,就按最大符合的字符匹配,匹配结果则是 "llo" 。1.5 优先级优先级符号最高\高()、(?:)、(?=)、[]中*、+、?、{n}、{n,}、{n,m}低^、$、元字符、任何字符次最低串接,即相邻字符连接在一起最低\ 2. Java与正则表达式JDK 中的 java.util.regex 包提供了对正则表达式的支持。java.util.regex 有三个核心类:Pattern 类:Pattern 是一个正则表达式的编译表示。Matcher 类:Matcher 是对输入字符串进行解释和匹配操作的引擎。PatternSyntaxException:PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。2.1 Pattern 类Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其静态方法compile,加载正则规则字符串,然后返回一个 Pattern 对象。与Pattern类一样,Matcher类也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象。【示例】Pattern 和 Matcher 的初始化Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content);2.2 Matcher 类Matcher 类可以说是 java.util.regex 中的核心类,它有三类功能:校验、查找、替换。2.2.1 校验为了校验文本是否与正则规则匹配,Matcher 提供了以下几个返回值为 boolean 的方法。序号方法及说明1public boolean lookingAt() 尝试将从区域开头开始的输入序列与该模式匹配。2public boolean find() 尝试查找与该模式匹配的输入序列的下一个子序列。3public boolean find(int start)重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。4public boolean matches() 尝试将整个区域与模式匹配。如果你傻傻分不清上面的查找方法有什么区别,那么下面一个例子就可以让你秒懂。【示例】lookingAt、find、matchespublic static void main(String[] args) { checkLookingAt("hello", "helloworld"); checkLookingAt("world", "helloworld"); checkFind("hello", "helloworld"); checkFind("world", "helloworld"); checkMatches("hello", "helloworld"); checkMatches("world", "helloworld"); checkMatches("helloworld", "helloworld"); } private static void checkLookingAt(String regex, String content) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); if (m.lookingAt()) { System.out.println(content + "\tlookingAt: " + regex); } else { System.out.println(content + "\tnot lookingAt: " + regex); } } private static void checkFind(String regex, String content) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); if (m.find()) { System.out.println(content + "\tfind: " + regex); } else { System.out.println(content + "\tnot find: " + regex); } } private static void checkMatches(String regex, String content) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); if (m.matches()) { System.out.println(content + "\tmatches: " + regex); } else { System.out.println(content + "\tnot matches: " + regex); } }输出:helloworld lookingAt: hello helloworld not lookingAt: world helloworld find: hello helloworld find: world helloworld not matches: hello helloworld not matches: world helloworld matches: helloworld说明regex = "world" 表示的正则规则是以 world 开头的字符串,regex = "hello" 和 regex = "helloworld" 也是同理。lookingAt方法从头部开始,检查 content 字符串是否有子字符串于正则规则匹配。find方法检查 content 字符串是否有子字符串于正则规则匹配,不管字符串所在位置。matches方法检查 content 字符串整体是否与正则规则匹配。2.2.2 查找为了查找文本匹配正则规则的位置,Matcher提供了以下方法:序号方法及说明1public int start() 返回以前匹配的初始索引。2public int start(int group) 返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引3public int end()返回最后匹配字符之后的偏移量。4public int end(int group)返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。5public String group()返回前一个符合匹配条件的子序列。6public String group(int group)返回指定的符合匹配条件的子序列。【示例】使用 start()、end()、group() 查找所有匹配正则条件的子序列public static void main(String[] args) { final String regex = "world"; final String content = "helloworld helloworld"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); System.out.println("content: " + content); int i = 0; while (m.find()) { i++; System.out.println("[" + i + "th] found"); System.out.print("start: " + m.start() + ", "); System.out.print("end: " + m.end() + ", "); System.out.print("group: " + m.group() + "\n"); } }输出content: helloworld helloworld [1th] found start: 5, end: 10, group: world [2th] found start: 16, end: 21, group: world2.2.3 替换替换方法是替换输入字符串里文本的方法:序号方法及说明1public Matcher appendReplacement(StringBuffer sb, String replacement)实现非终端添加和替换步骤。2public StringBuffer appendTail(StringBuffer sb)实现终端添加和替换步骤。3public String replaceAll(String replacement) 替换模式与给定替换字符串相匹配的输入序列的每个子序列。4public String replaceFirst(String replacement) 替换模式与给定替换字符串匹配的输入序列的第一个子序列。5public static String quoteReplacement(String s)返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给 Matcher 类的 appendReplacement 方法一个字面字符串一样工作。【示例】replaceFirst 和 replaceAllpublic static void main(String[] args) { String regex = "can"; String replace = "can not"; String content = "I can because I think I can."; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); System.out.println("content: " + content); System.out.println("replaceFirst: " + m.replaceFirst(replace)); System.out.println("replaceAll: " + m.replaceAll(replace)); }输出content: I can because I think I can. replaceFirst: I can not because I think I can. replaceAll: I can not because I think I can not.说明replaceFirst:替换第一个匹配正则规则的子序列。replaceAll:替换所有匹配正则规则的子序列。【示例】appendReplacement、appendTail 和 replaceAllpublic static void main(String[] args) { String regex = "can"; String replace = "can not"; String content = "I can because I think I can."; StringBuffer sb = new StringBuffer(); StringBuffer sb2 = new StringBuffer(); System.out.println("content: " + content); Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); while (m.find()) { m.appendReplacement(sb, replace); } System.out.println("appendReplacement: " + sb); m.appendTail(sb); System.out.println("appendTail: " + sb); }输出content: I can because I think I can. appendReplacement: I can not because I think I can not appendTail: I can not because I think I can not.说明从输出结果可以看出,appendReplacement和appendTail方法组合起来用,功能和replaceAll是一样的。如果你查看replaceAll的源码,会发现其内部就是使用appendReplacement和appendTail方法组合来实现的。【示例】quoteReplacement 和 replaceAll,解决特殊字符替换问题public static void main(String[] args) { String regex = "\\$\\{.*?\\}"; String replace = "${product}"; String content = "product is ${productName}."; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); String replaceAll = m.replaceAll(replace); System.out.println("content: " + content); System.out.println("replaceAll: " + replaceAll); }输出Exception in thread "main" java.lang.IllegalArgumentException: No group with name {product} at java.util.regex.Matcher.appendReplacement(Matcher.java:849) at java.util.regex.Matcher.replaceAll(Matcher.java:955) at org.zp.notes.javase.regex.RegexDemo.wrongMethod(RegexDemo.java:42) at org.zp.notes.javase.regex.RegexDemo.main(RegexDemo.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)说明String regex = "\\$\\{.*?\\}";表示匹配类似${name}这样的字符串。由于$、{ 、}都是特殊字符,需要用反义字符\来修饰才能被当做一个字符串字符来处理。上面的例子是想将 ${productName} 替换为 ${product} ,然而replaceAll方法却将传入的字符串中的$当做特殊字符来处理了。结果产生异常。如何解决这个问题?JDK1.5 引入了quoteReplacement方法。它可以用来转换特殊字符。其实源码非常简单,就是判断字符串中如果有\或$,就为它加一个转义字符\我们对上面的代码略作调整:m.replaceAll(replace)改为m.replaceAll(Matcher.quoteReplacement(replace)),新代码如下:public static void main(String[] args) { String regex = "\\$\\{.*?\\}"; String replace = "${product}"; String content = "product is ${productName}."; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(content); String replaceAll = m.replaceAll(Matcher.quoteReplacement(replace)); System.out.println("content: " + content); System.out.println("replaceAll: " + replaceAll); }输出content: product is ${productName}. replaceAll: product is ${product}.说明字符串中如果有\或$,不能被正常解析的问题解决。3. Python与正则表达式正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。re 模块使 Python 语言拥有全部的正则表达式功能。compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。本章节主要介绍Python中常用的正则表达式处理函数。3.1 re.match函数re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。函数语法:re.match(pattern, string, flags=0)函数参数说明:参数描述pattern匹配的正则表达式string要匹配的字符串。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志匹配成功re.match方法返回一个匹配的对象,否则返回None。我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。匹配对象方法描述group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re print(re.match('www', 'www.fxkxb.com').span()) # 在起始位置匹配 print(re.match('com', 'www.fxkxb.com')) # 不在起始位置匹配 以上实例运行输出结果为:(0, 3) None实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re line = "Cats are smarter than dogs" matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I) if matchObj: print("matchObj.group() : ", matchObj.group()) print("matchObj.group(1) : ", matchObj.group(1)) print("matchObj.group(2) : ", matchObj.group(2)) else: print("No match!!")以上实例执行结果如下:matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats matchObj.group(2) : smarter3.2 re.search方法re.search 扫描整个字符串并返回第一个成功的匹配。函数语法:re.search(pattern, string, flags=0)函数参数说明:参数描述pattern匹配的正则表达式string要匹配的字符串。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。匹配成功re.search方法返回一个匹配的对象,否则返回None。我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。匹配对象方法描述group(num=0)匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。groups()返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re print(re.search('www', 'www.fxkxb.com').span()) # 在起始位置匹配 print(re.search('com', 'www.fxkxb.com').span()) # 不在起始位置匹配 以上实例运行输出结果为:(0, 3) (10, 13)实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re line = "Cats are smarter than dogs" searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I) if searchObj: print("searchObj.group() : ", searchObj.group()) print("searchObj.group(1) : ", searchObj.group(1)) print("searchObj.group(2) : ", searchObj.group(2)) else: print("Nothing found!!")以上实例执行结果如下:searchObj.group() : Cats are smarter than dogs searchObj.group(1) : Cats searchObj.group(2) : smarter3.3 re.match与re.search的区别re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re line = "Cats are smarter than dogs" matchObj = re.match(r'dogs', line, re.M | re.I) if matchObj: print("match --> matchObj.group() : ", matchObj.group()) else: print("No match!!") matchObj = re.search(r'dogs', line, re.M | re.I) if matchObj: print("search --> searchObj.group() : ", matchObj.group()) else: print("No match!!")以上实例运行结果如下:No match!! search --> searchObj.group() : dogs3.4 检索和替换Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。语法:re.sub(pattern, repl, string, count=0, flags=0)参数:pattern : 正则中的模式字符串。repl : 替换的字符串,也可为一个函数。string : 要被查找替换的原始字符串。count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re phone = "2004-959-559 # 这是一个国外电话号码" # 删除字符串中的 Python注释 num = re.sub(r'#.*$', "", phone) print("电话号码是: ", num) # 删除非数字(-)的字符串 num = re.sub(r'\D', "", phone) print("电话号码是 : ", num) 以上实例执行结果如下:电话号码是: 2004-959-559 电话号码是 : 20049595593.4.1 repl 参数是一个函数以下实例中将字符串中的匹配的数字乘以 2:实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re # 将匹配的数字乘以 2 def double(matched): value = int(matched.group('value')) return str(value * 2) s = 'A23G4HFD567' print(re.sub('(?P<value>\d+)', double, s))执行输出结果为:A46G8HFD11343.4.2 re.compile 函数compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。语法格式为:re.compile(pattern[, flags])参数:pattern : 一个字符串形式的正则表达式flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:re.I 忽略大小写re.L 表示特殊字符集 w, W, b, B, s, S 依赖于当前环境re.M 多行模式re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)re.U 表示特殊字符集 w, W, b, B, d, D, s, S 依赖于 Unicode 字符属性数据库re.X 为了增加可读性,忽略空格和 # 后面的注释实例>>>import re >>> pattern = re.compile(r'\d+') # 用于匹配至少一个数字 >>> m = pattern.match('one12twothree34four') # 查找头部,没有匹配 >>> print m None >>> m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配 >>> print m None >>> m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配 >>> print m # 返回一个 Match 对象 <_sre.SRE_Match object at 0x10a42aac0> >>> m.group(0) # 可省略 0 '12' >>> m.start(0) # 可省略 0 3 >>> m.end(0) # 可省略 0 5 >>> m.span(0) # 可省略 0 (3, 5)在上面,当匹配成功时返回一个 Match 对象,其中:group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;span([group]) 方法返回 (start(group), end(group))。再看看一个例子:实例>>>import re >>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I 表示忽略大小写 >>> m = pattern.match('Hello World Wide Web') >>> print m # 匹配成功,返回一个 Match 对象 <_sre.SRE_Match object at 0x10bea83e8> >>> m.group(0) # 返回匹配成功的整个子串 'Hello World' >>> m.span(0) # 返回匹配成功的整个子串的索引 (0, 11) >>> m.group(1) # 返回第一个分组匹配成功的子串 'Hello' >>> m.span(1) # 返回第一个分组匹配成功的子串的索引 (0, 5) >>> m.group(2) # 返回第二个分组匹配成功的子串 'World' >>> m.span(2) # 返回第二个分组匹配成功的子串 (6, 11) >>> m.groups() # 等价于 (m.group(1), m.group(2), ...) ('Hello', 'World') >>> m.group(3) # 不存在第三个分组 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: no such group3.4.3 findall在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。注意: match 和 search 是匹配一次 findall 匹配所有。语法格式为:findall(string[, pos[, endpos]])参数:string : 待匹配的字符串。pos : 可选参数,指定字符串的起始位置,默认为 0。endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。查找字符串中的所有数字:实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re pattern = re.compile(r'\d+') # 查找数字 result1 = pattern.findall('runoob 123 google 456') result2 = pattern.findall('run88oob123google456', 0, 10) print(result1) print(result2)输出结果:['123', '456'] ['88', '12']3.4.4 re.finditer和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。re.finditer(pattern, string, flags=0)参数:参数描述pattern匹配的正则表达式string要匹配的字符串。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志实例#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ @file : regex.py @author : Leon(fxkxb.com) @date : October 08, 2021 15:49 @version : 1.0 @description : """ import re it = re.finditer(r"\d+", "12a32bc43jf3") for match in it: print(match.group())输出结果:12 32 43 33.4.5 re.splitsplit 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:re.split(pattern, string[, maxsplit=0, flags=0])参数:参数描述pattern匹配的正则表达式string要匹配的字符串。maxsplit分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。flags标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志实例>>>import re >>> re.split('\W+', 'runoob, runoob, runoob.') ['runoob', 'runoob', 'runoob', ''] >>> re.split('(\W+)', ' runoob, runoob, runoob.') ['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', ''] >>> re.split('\W+', ' runoob, runoob, runoob.', 1) ['', 'runoob, runoob, runoob.'] >>> re.split('a*', 'hello world') # 对于一个找不到匹配的字符串而言,split 不会对其作出分割 ['hello world']3.5 正则表达式对象3.5.1 re.RegexObjectre.compile() 返回 RegexObject 对象。3.5.2 re.MatchObjectgroup() 返回被 RE 匹配的字符串。start() 返回匹配开始的位置end() 返回匹配结束的位置span() 返回一个元组包含匹配 (开始,结束) 的位置3.6 正则表达式修饰符 - 可选标志正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:修饰符描述re.I使匹配对大小写不敏感re.L做本地化识别(locale-aware)匹配re.M多行匹配,影响 ^ 和 $re.S使 . 匹配包括换行在内的所有字符re.U根据Unicode字符集解析字符。这个标志影响 w, W, b, B.re.X该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。4. 通用实例4.1 校验中文校验字符串中只能有中文字符(不包括中文标点符号)。中文字符的 Unicode 编码范围是 \u4e00 到 \u9fa5。如有兴趣,可以参考百度百科-Unicode 。^[\u4e00-\u9fa5]+$匹配: 春眠不觉晓不匹配:春眠不觉晓,4.2 校验身份证号码身份证为 15 位或 18 位。15 位是第一代身份证。从 1999 年 10 月 1 日起,全国实行公民身份证号码制度,居民身份证编号由原 15 位升至 18 位。15 位身份证:由 15 位数字组成。排列顺序从左至右依次为:六位数字地区码;六位数字出生日期;三位顺序号,其中 15 位男为单数,女为双数。18 位身份证:由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地区码;八位数字出生日期;三位数字顺序码和一位数字校验码(也可能是 X)。身份证号含义详情请见:百度百科-居民身份证号码4.3 地区码(6 位)(1[1-5]|2[1-3]|3[1-7]|4[1-3]|5[0-4]|6[1-5])\d{4}出生日期(8 位)匹配18位身份证:^((1[1-5]|2[1-3]|3[1-7]|4[1-3]|5[0-4]|6[1-5])\d{4})\d{4}((0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01]))(\d{3}(\d|X))$注:下面的是 18 位身份证的有效出生日期,如果是 15 位身份证,只要将第一个d{4}改为d{2}即可。((\d{4}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012])(0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229)15 位有效身份证^((1[1-5]|2[1-3]|3[1-7]|4[1-3]|5[0-4]|6[1-5])\d{4})((\d{2}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012])(0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229)(\d{3})$匹配:110001700101031不匹配:11000170150103118 位有效身份证^((1[1-5]|2[1-3]|3[1-7]|4[1-3]|5[0-4]|6[1-5])\d{4})((\d{4}((0[13578]|1[02])(0[1-9]|[12]\d|3[01])|(0[13456789]|1[012])(0[1-9]|[12]\d|30)|02(0[1-9]|1\d|2[0-8])))|([02468][048]|[13579][26])0229)(\d{3}(\d|X))$匹配:110001199001010310 | 11000019900101015X不匹配:990000199001010310 | 1100011990130103104.4 校验有效用户名、密码描述:长度为 6-18 个字符,允许输入字母、数字、下划线,首字符必须为字母。^[a-zA-Z]\w{5,17}$匹配:he_llo@worl.d.com | hel.l-o@wor-ld.museum | h1ello@123.com不匹配:hello@worl_d.com | he&llo@world.co1 | .hello@wor#.co.uk4.5 校验邮箱描述:不允许使用 IP 作为域名,如 : hello@154.145.68.12@符号前的邮箱用户和.符号前的域名(domain)必须满足以下条件:字符只能是英文字母、数字、下划线_、.、- ;首字符必须为字母或数字;_、.、- 不能连续出现。域名的根域只能为字母,且至少为两个字符。^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$匹配:he_llo@worl.d.com | hel.l-o@wor-ld.museum | h1ello@123.com不匹配:hello@worl_d.com | he&llo@world.co1 | .hello@wor#.co.uk4.6 校验 URL描述:校验 URL。支持 http、https、ftp、ftps。^(ht|f)(tp|tps)\://[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3})?(/\S*)?$匹配:http://google.com/help/me | http://www.google.com/help/me/ | https://www.google.com/help.asp | ftp://www.google.com | ftps://google.org不匹配:http://un/www.google.com/index.asp4.7 校验时间描述:校验时间。时、分、秒必须是有效数字,如果数值不是两位数,十位需要补零。^([0-1][0-9]|[2][0-3]):([0-5][0-9])$匹配:00:00:00 | 23:59:59 | 17:06:30不匹配:17:6:30 | 24:16:304.8 校验日期描述:校验日期。日期满足以下条件:格式 yyyy-MM-dd 或 yyyy-M-d连字符可以没有或是“-”、“/”、“.”之一闰年的二月可以有 29 日;而平年不可以。一、三、五、七、八、十、十二月为 31 日。四、六、九、十一月为 30 日。^(?:(?!0000)[0-9]{4}([-/.]?)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2\2(?:29))$匹配:2016/1/1 | 2016/01/01 | 20160101 | 2016-01-01 | 2016.01.01 | 2000-02-29不匹配:2001-02-29 | 2016/12/32 | 2016/6/31 | 2016/13/1 | 2016/0/14.9 校验中国手机号码描述:中国手机号码正确格式:11 位数字。移动有 16 个号段:134、135、136、137、138、139、147、150、151、152、157、158、159、182、187、188。其中 147、157、188 是 3G 号段,其他都是 2G 号段。联通有 7 种号段:130、131、132、155、156、185、186。其中 186 是 3G(WCDMA)号段,其余为 2G 号段。电信有 4 个号段:133、153、180、189。其中 189 是 3G 号段(CDMA2000),133 号段主要用作无线网卡号。总结:13 开头手机号 0-9;15 开头手机号 0-3、5-9;18 开头手机号 0、2、5-9。此外,中国在国际上的区号为 86,所以手机号开头有+86、86 也是合法的。以上信息来源于 百度百科-手机号^((\+)?86\s*)?((13[0-9])|(15([0-3]|[5-9]))|(18[0,2,5-9]))\d{8}$匹配:+86 18012345678 | 86 18012345678 | 15812345678不匹配:15412345678 | 12912345678 | 1801234567894.10 校验中国固话号码描述:固话号码,必须加区号(以 0 开头)。 3 位有效区号:010、020~029,固话位数为 8 位。 4 位有效区号:03xx 开头到 09xx,固话位数为 7。如果想了解更详细的信息,请参考 百度百科-电话区号 。^(010|02[0-9])(\s|-)\d{8}|(0[3-9]\d{2})(\s|-)\d{7}$匹配:010-12345678 | 010 12345678 | 0512-1234567 | 0512 1234567不匹配:1234567 | 123456784.11 校验 IPv4 地址描述:IP 地址是一个 32 位的二进制数,通常被分割为 4 个“8 位二进制数”(也就是 4 个字节)。IP 地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d 都是 0~255 之间的十进制整数。^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$匹配:0.0.0.0 | 255.255.255.255 | 127.0.0.1不匹配:10.10.10 | 10.10.10.2564.12 校验 IPv6 地址描述:IPv6 的 128 位地址通常写成 8 组,每组为四个十六进制数的形式。IPv6 地址可以表示为以下形式:IPv6 地址零压缩 IPv6 地址(section 2.2 of rfc5952)带有本地链接区域索引的 IPv6 地址 (section 11 of rfc4007)嵌入 IPv4 的 IPv6 地址(section 2 of rfc6052映射 IPv4 的 IPv6 地址 (section 2.1 of rfc2765)翻译 IPv4 的 IPv6 地址 (section 2.1 of rfc2765)显然,IPv6 地址的表示方式很复杂。你也可以参考:百度百科-IPv6Stack overflow 上的 IPv6 正则表达高票答案(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))匹配:1:2:3:4:5:6:7:8 | 1:: | 1::8 | 1::6:7:8 | 1::5:6:7:8 | 1::4:5:6:7:8 | 1::3:4:5:6:7:8 | ::2:3:4:5:6:7:8 | 1:2:3:4:5:6:7:: | 1:2:3:4:5:6::8 | 1:2:3:4:5::8 | 1:2:3:4::8 | 1:2:3::8 | 1:2::8 | 1::8 | ::8 | fe80::7:8%1 | ::255.255.255.255 | 2001:db8:3:4::192.0.2.33 | 64:ff9b::192.0.2.33不匹配:1.2.3.4.5.6.7.8 | 1::2::35. 工具Regexper : https://regexper.com/Regulex : https://jex.im/regulex/RegExr : https://regexr.com/6. 参考正则表达式 - 维基百科 : https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8FRegular expression - Wikipedia : https://en.wikipedia.org/wiki/Regular_expression正则表达式 - 百度百科 : https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F正则表达式 - 百度百科 : https://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F正则表达式 – 教程 | 菜鸟教程 : https://www.runoob.com/regexp/regexp-tutorial.htmlJava 正则表达式 | 菜鸟教程 : https://www.runoob.com/java/java-regular-expressions.htmlJava 正则从入门到精通 : https://github.com/dunwu/javacore/blob/master/docs/advanced/java-regex.mdPython 正则表达式 | 菜鸟教程 : https://www.runoob.com/python/python-reg-expressions.html... ↩0-9 ↩
2021年10月08日
327 阅读
2 评论
1 点赞
1
2