代码编织梦想

学习资源

书籍:正则表达式必知必会

正则表达式

正则表达式(REGEX)(Regular Express)

一、概念

正则表达式就是由普通字符以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式用来描述字符串的特征。

个人理解:正则表达式即用于检索、匹配、校验、替换字符串的文字模板。

作用

  1. **检索:**通过正则表达式,从字符串中获取我们想要的部分
  2. **匹配:**判断给定的字符串是否符合正则表达式的过滤逻辑
  3. 替换

正则表达式是非常复杂的,理解正则表达式能做什么(字符串匹配、字符串提取、字符串替换),掌握常用的正则表达式用法。

3个重要的正则表达式命令

  1. 在正则表达式中有三种类型的括号,[]、{}、()。中括号[]内是需要匹配的字符,大括号{}内是指定匹配字符的数量,小括号()则是用来改变优先级或分组的

  2. 插入符号"^"表示正则式的开始,在[]中表示“非”

  3. 美元符号"$"表示正则式的结束

    eg:Regex obj = new Regex("[a-z]{10}]");//搜索长度为10的a-z的英文字母

二、元字符
. 除\n以外的任意的单个字符		注:有且只有一个
[] 字符组:[]表示在字符组中罗列出来的字符,任意取单个。		eg:a[^a-zA-Z王]b		-表示范围,-在第一位时只表示一个字符,不表示元字符;^表示排除
以下是通配符:
| 表示“或”的意思			正则表达式尽量减少“|”的使用,“|”越多,越消耗性能
* 表示限定前面的表达式出现0次或者多次
+ 表示限定前面的表达式一次或多次,至少一次
? 表示限定前面的表达式出现0次或1次	
		注意.与*、+、?的区别
{} 指定匹配字符的数量		eg:[0-9]{8}		[a-z]{4,}

贪婪型量词和懒惰型量词

  • +、*和?也叫作量词
  • 区别
    • 前者会尽可能多地匹配,后者会尽可能少的匹配
    • 贪婪型会尽可能从一段文本的开头匹配到结尾,懒惰型碰到第一个匹配后就会停止
贪婪型量词懒惰型量词
**?
++?
{n,}{n,}?

eg:

文本
this offer is not available to customers living in <b>AK</b> and <b>HI</b>

正则表达式	贪婪型
<[Bb]>.*<\/[Bb]>
结果:一处匹配	<b>AK</b> and <b>HI</b>

正则表达式	懒惰型
<[Bb]>.*?<\/[Bb]>
结果:两处匹配	<b>AK</b>		<b>HI</b>
[0-9]	\d		\D取余
[A-Za-z0-9_]	\w		\W取余
[\f\n\r\t\v]	\s	表示所有不可见字符		\S取余
\b单词边界		\B取余.	\b匹配的是字符之间的一个位置:一边是能够被\w匹配的字母数字和下划线,另一边是能够被\W匹配的字符

\x	十六进制
\o	八进制
\uxxxx匹配Unicode编码

注:要想完全匹配,必须要加^和$

反向引用

反向引用:子表达式用来定义字符或表达式的集合。除了可以用于重复匹配,还可以在模式的内部被引用,这种引用被称为反向引用。

eg:查找重复单词

this is a block of of text

正则表达式:[ ]+(\w+)[ ]+\1

this is a block of of text

\1表示匹配模式中所使用的第一个子表达式,\2,\3…以此类推

  • 可以把反向引用想象成变量
  • 反向引用只能用来引用括号里的子表达式
  • 反向引用匹配通常从1开始计数看,\0可以用来代表整个正则表达式

eg:匹配正确的标题标签内容

<h3>fasd</h3>
<h2>fasd</h3>

<[Hh](1-6)>.*?</[Hh]\1>

环视(lookaround)

环视:该模式是为了找出正确的匹配,而其自身不属于最终的匹配结果。分为向前查看和向后查看。环视可以更精细地控制最终的返回结果

  • 所有语言都支持向前查看,java支持向后查看,js不支持向后查看
  • 向前查看模式长度可变,比较灵活;向后查看只能是固定长度
  • 否定式环视,即不包含
种类说明
(?=)肯定式向前查看
(?!)否定式向前查看
(?<=)肯定式向后查看
(?<!)否定式向后查看

eg:提取url的协议部分

http://www.baidu.com
https://mail.forta.com
ftp://ftp.baidu.com

正则表达式:.*(?=:)

http😕/www.baidu.com
https😕/mail.forta.com
ftp😕/ftp.baidu.com

结果中就不包含“:”

eg:结合向前查看和向后查看,提取标题中的文本内容(不包含标题)

<title>dfshal</title>

正则表达式:(?<=\<[Tt][Ii][Tt][Ll][Ee]).*(?=</[Tt][Ii][Tt][Ll][Ee]>)

<title>dfshal</title>

编程语言中的正则表达式

JavaScript

两种创建方式:

  1. 直接量

    • var reg = /abc/im;
      	i:ingoreCase
      	g:global,全局匹配(查找所有匹配而非在找到第一个匹配后停止)
      	m:multiline,执行多行匹配
      
  2. new RegExp(“正则表达式”);

reg.test(),检测是否匹配

str.match(reg),返回匹配数组

Java

java.util.regex包

  • Pattern 正则表达式的编译表示
    • compile 编译一个正则表达式为Pattern对象
    • matcher 用Pattern对象匹配一个字符串,返回匹配结果
  • Matcher
    • Index Methods(位置方法) //start(),start(int group),end(),end(int group)
    • Search Methods(查找方法) //lookingAt(),find(),find(int start),matches()
      • lookingAt()//部分匹配
      • matches()//完全匹配
    • Replacement Methods(替换方法) //replaceAll(String replacement)

eg

private static final String REGEX = "\\bdog\\b";//\b表示边界private static final String INPUT = "dog dog dog doggie dogg";public static void main(String[] args) {    //检查字符串里面有多少个dog    Pattern p = Pattern.compile(REGEX);    Matcher m = p.matcher(INPUT);    int count = 0;    while (m.find()) {        count++;        System.out.println("count = " + count);        System.out.println("m = " + m.start());        System.out.println("m.end() = " + m.end());    }}
private static final String REGEX = "Foo";private static final String INPUT = "Foooooooo";private static Pattern pattern;private static Matcher matcher;public static void main(String[] args) {    //Initialize    pattern = Pattern.compile(REGEX);    matcher = pattern.matcher(INPUT);    System.out.println("REGEX = " + REGEX);    System.out.println("INPUT = " + INPUT);    System.out.println("matcher.lookingAt() = " + matcher.lookingAt());//部分匹配    System.out.println("matcher.matches() = " + matcher.matches());//完全匹配}
private static String REGEX = "a*b";//*表示限定前面的a可以有0或多个private static String INPUT = "aabfooaabfooabfoobcdd";private static String REPLACE = "-";public static void main(String[] args) {    Pattern pattern = Pattern.compile(REGEX);    Matcher matcher = pattern.matcher(INPUT);    StringBuffer stringBuffer = new StringBuffer();    //全部替换    while (matcher.find()) {        matcher.appendReplacement(stringBuffer, REPLACE);    }    //将最后的尾巴字符串附加上    matcher.appendTail(stringBuffer);    System.out.println("stringBuffer.toString() = " + stringBuffer.toString());}
private static String REGEX="dog";private static String INPUT="The dog says meow.All dogs say meow.";private static String REPLACE="cat";public static void main(String[] args) {    Pattern pattern=Pattern.compile(REGEX);    Matcher matcher=pattern.matcher(INPUT);    INPUT=matcher.replaceAll(REPLACE);//将所有的dog换成cat    System.out.println("INPUT = " + INPUT);}
C#

添加引用

using System.Text.RegularExpressions;

常用方法

IsMacth():	用来判断给定的字符串是否匹配某个正则表达式Match():	用来从给定的字符串中按照正则表达式的要求提取【一个】匹配的字符串		一般字符串提取不加^和$Matches():	【所有】匹配的字符串Replace():	替换字符串
Match.Value表示本次提取到的字符串Match.Groups集合中存储的就是所有的分组信息Match.Groups[0].Value	表示这次提取的整个字符串Match.Groups[1].Value	表示这次提取的字符串中的第一个分组字符串

正则表达式的常见用法

ip地址
(((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d{1,2})|(1\d{2})|(2[0-4]\d)|(25[0-5]))
邮箱地址
(\w+\.)*\w+@(\w+\.)+[A-Za-z]+
提取标签中的内容:以title为例
(?<=\<[Tt][Ii][Tt][Ll][Ee]).*(?=\<\[Tt][Ii][Tt][Ll][Ee]>)
html注释
(?<=\<!--\s*).*(?=\s*-->)
网址url
[a-zA-z]+://[^\s]*
QQ号码
[1-9][0-9]{4,}
18位身份证
^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/qq_42002500/article/details/111090265

剑指offer 二维数组中的查找java实现-爱代码爱编程

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。 请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 示例: 现有矩阵 matrix 如下: [ [1, 4, 7, 11, 15], [2, 5, 8, 12, 19], [3, 6, 9, 1

《APP架构师实践指南》读书笔记-爱代码爱编程

全书分15个章节,概述了作为一个APP客户端架构师所要掌握的技能图谱,作为安卓开发者,所以里面所有iOS的内容我自动跳过了,这里也作为一些记录,有的是我实践过的,有的是待验证的,留作记录。 眼界的拓展: 架构的核心是功能、安全、性能和稳定。 职责包括选型规划、架构设计、技术攻关、沟通协调、疑难攻略等。 封装、继承、多态 到底什么是封装?

哈希表的常用操作-爱代码爱编程

import java.util.HashMap; public class HashTableUse { //java是HashMap,python是字典,是键值对,是key-value //key通过哈希函数,确定一块内存地址,存放key/value //哈希碰撞:不同key,通过哈希函数得到同一个内存地址,通过链表的方法,将

Spring源码学习-爱代码爱编程

Spring学习 源码部分获取XML的验证方式IOC容器常用的Bean注入的方法xml配置文件config配置类Import注解实现ImportSelector接口实现ImportBeanDefinitionRegistrar接口实现FactoryBean接口 源码部分 获取XML的验证方式 XML文件比较常用的验证模式,DTD和XSD

001-Java学习前基础-爱代码爱编程

目录 前言一、Java语言特性(简单概述)二、JDK、JRE、JVM三者关系三、java文件的加载与执行 前言 今天是我初次写博客,想通过这种方式把自己学过的东西梳理一遍,加深自己的记忆,笔记中借鉴了一些老师的笔记加上自己的整理和理解,希望大家可以多多交流学习,写的不好或者有错的地方还请大家多指正! 一、Java语言特性(简单概述) 简

简单理解Collections.synchronizedList-爱代码爱编程

大家都知道ArrayList并不是线程安全的,如果想要做到线程安全,我们可以使用 Collections.synchronizedList, 但是使用 Collections.synchronizedList后是否真的就线程安全了? 1. Collections.synchronizedList 原理 工欲善其事必先利其器,我们先来看看Colle

python爬虫之正则表达式的运用-爱代码爱编程

一.什么是正则表达式? 通俗的理解就是对于一个目标串,我们通过正则表达式制定的一些规则和用法可以对这个目标串进行子串的模式匹配从而获得我们想要的数据,正则表达式能高效灵活的提取数据 二.使用正则表达式 A.库文件 python的标准库当中re库包含了正则表达式的用法 我们只需要调用即可 import re B.常用的函数 1.search函

正则表达式(Regular expression)学习记录1-爱代码爱编程

正则表达式(Regular expression)学习记录1 作为学习更新类文章,就不像解决问题向文章那样步骤清晰,可能会有点拖泥带水,这只是我的个人学习记录,感兴趣的可以一起学习 正则表达式在程序圈内也算是一个很受欢迎的工具,利用好正则表达式能有效提高我们的工作效率,有效减少if-else的使用次数 分享一个收藏很久的正则在线验证工具 https:

通用正则表达式总结-爱代码爱编程

通用正则表达式总结 一、概念 正则表达式(Regular Expression)是一种特殊的字符串模式,用于定义一种规则去匹配符合规则的字符。 二、用途 用途例子涉及类字符串的匹配(字符匹配)IP地址是否正确java.lang.String字符串查找从网页中揪出Email地址java.util.regex.Pattern字符串替换将手机号部分替换成

java—String类型的常用方法-爱代码爱编程

1. int length():返回字符串的长度: return value.length char charAt(int index): 返回某索引处的字符return value[index] boolean isEmpty():判断是否是空字符串:return value.length == 0 String toLowerCase():使用默认语