正则表达式

1.正则表达式

1.简介

  • 1.正则表达式(Regular Expression):是由普通字符(a~z/1~9等)和特殊字符(元字符)组成的文本模式,用来描述和匹配字符串的特定模式
  • 2.正则表达式的组件可以是单个字符字符集合字符范围字符间的选择或这些组件的任意组合
  • 3.正则表达式用于模式匹配和搜索文本,其提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据
  • 4.正则表达式可以应用于各种编程语言和文本处理工具中

2.模式

1.字符匹配

  • 1.普通字符:按照字面含义进行匹配(字母、数字、空格等,如a将匹配到文本中的小写a字母)
  • 2.元字符:具有特殊的含义字符,元字符可以分为以下类型

1.基本元字符

元字符 含义 实例
. 匹配除换行符(\n\r)之外的任何单个字符,如果想要匹配包括换行符\n在内的任何字符,可使用`(. \n)`模式
` ` 逻辑或运算符,用于指定多个模式的选择
[ ] 匹配该字符集合中的任意一个字符 [abc]可以匹配abandoned中的ab
[^] 匹配非该字符集合中的任意字符 [^abc]可以匹配plan中的pln
- 定义一个范围 a-z表示从小写字母a到小写字母z,一般配合[ ]使用
[a-z] 匹配指定范围内的任意字符 [1-9]可以匹配plan666中的6
[^a-z] 匹配非指定范围内的任意字符 [^a-z]可以匹配非小写字母中的数据
\ 转义字符,将含有特殊含义的字符转为普通字符 |将`

2.量词元字符

元字符 含义 实例
? 匹配前面的 字符/子表达式 零次或一次 do(es)?可以匹配dodoes,等价于{0,1}
* 匹配前面的 字符/子表达式 零次或多次 zo*可以匹配zzoo,等价于{0,}
+ 匹配前面的 字符/子表达式 一次或多次 zo+可以匹配zozoo,等价于{1,}
{n} 匹配前面的 字符/子表达式 恰好 n o{2}可以匹配food中的oo
{n,} 匹配前面的 字符/子表达式 至少 n o{2,}可以匹配food中的oo
{n,m} 匹配前面的 字符/子表达式 至少 n 次且不超过 m o{1,3} 可以匹配foooood中的前三个 o
*?+?{n,}?{n,m}? 对应量词的懒惰型版本,懒惰型版本量词在第一次匹配上时就会停止匹配 o{1,3}? 匹配到foooood中的第一个 o就直接停止匹配

3.位置元字符

元字符 含义 实例
^ 匹配输入字符串的开始位置 ^t只能匹配到test首位的t
\A 匹配输入字符串的开始位置 等同于^
$ 匹配输入字符串的结束位置 t$只能匹配到test末尾的t
\z 匹配输入字符串的结束位置 等同于$
\b 匹配单词边界(开始位置`\b`在前和结束位置`\b`在后) \bab只能匹配到abccab首位的abab\b只能匹配到abccab末尾的ab
\B 匹配非单词边界(中间位置) \Bab只能匹配到abcabcab中间和末尾的abab\B只能匹配到abcabcab中间和首位的ab

4.特殊元字符

元字符 含义 实例
[\b] 匹配退格字符
\c 匹配一个控制字符(控制字符即ASCII的0到31,再加上ASCII的127)
\d 匹配任意一个数字字符,等价于[0-9] \d可以匹配ab123ab中的1/2/3
\D \d的反义,匹配任意一个非数字字符,等价于 [^0-9] \D可以匹配ab123ab中的a/b
\f 匹配一个换页符,等价于\x0c\cL \f可以匹配ab123\fab中的\f
\n 匹配一个换行符,等价于\x0a\cJ \n可以匹配ab123\nab中的\n
\r 匹配一个回车符,等价于\x0d\cM \r可以匹配ab123\rab中的\r
\s 匹配任意空白字符,包括空格、制表符、换页符等,等价于`空格\f\n\r\t` \s可以匹配ab123\sab中的\s
\t 匹配一个制表符(Tab键),等价于\x09\cI \t可以匹配ab123\tab中的\t
\v 匹配一个垂直制表符,等价于\x0b\cK \v可以匹配ab123\vab中的\v
\w 匹配任意字母、数字或下划线,等价于[A-Za-z0-9_] \w可以匹配ab123ab_中的任意一个字符
\W \w的反义,匹配任意非字母、数字或下划线,等价于 [^A-Za-z0-9_] \W无法匹配ab123ab_中的任意一个字符
\x 匹配一个十六进制数字 \x41可以匹配Ab123ab中的A

5.反向引用和环视元字符

元字符 含义 实例
() 定义一个子表达式并捕获匹配结果
(?: ) 定义一个子表达式但不捕获匹配结果
\1 匹配第一个子表达式;\2匹配第二个子表达式,以此类推
?= 肯定式向前查看
?= 匹配任意数字字符
?<= 肯定式向后查看
?! 否定式向前查看
?<! 否定式向后查看
?() 条件( if then )
`?() ` 条件(if then else)

6.大小写转换元字符

元字符 含义 实例
\E 结束\L或\U转换
\I 把下一个字符转为小写
\L 把后面的字符转换为小写,直到遇到 \E 为止
\u 把下一个字符转换为大写
\U 把后面的字符转换为大写,直到遇见 \E 为止

7.匹配模式

元字符 含义 实例
(?m) 多行模式,多行模式迫使正则表达式引擎将换行符视为字符串分隔符

6.实例

  • 1.^为匹配输入字符串的开始位置
  • 2.0-9 匹配单个数字,+ 匹配一个或者多个,0-9+匹配多个数字
  • 3.abc 匹配字母 a b c 并以 a b c 结尾, 匹配字母 abc 并以 abc 结尾, 匹配字母abc并以abc结尾, 为匹配输入字符串的结束位置
  • 4.只允许用户名包含字符、数字、下划线和连接字符 -,并设置用户名的长度

3.语法

  • 1.普通字符
    • 1.普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号
    • 2.[ABC]:匹配 ... 中的所有字符,例如 aeiou 匹配字符串 "google runoob taobao" 中所有的 e o u a 字母
    • 3.[^ABC]:匹配除了 ... 中字符的所有字符,例如 \^aeiou 匹配字符串 "google runoob taobao" 中除了 e o u a 字母的所有字符
    • 4.[A-Z]A-Z 表示一个区间,匹配所有大写字母,a-z 表示所有小写字母
    • 5.. 匹配除换行符(\n、\r)之外的任何单个字符,相等于 \^\\n\\r
    • 6.[\s\S]:匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行
    • 7.\w:匹配字母、数字、下划线。等价于 A-Za-z0-9_
  • 2.非打印字符
    • 1.非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列
    • 2.\cx:匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符
    • 3.\f:匹配一个换页符。等价于 \x0c 和 \cL
    • 4.\n:匹配一个换行符。等价于 \x0a 和 \cJ
    • 5.\r:匹配一个回车符。等价于 \x0d 和 \cM
    • 6.\s:匹配任何空白字符,包括空格、制表符、换页符等等。等价于 \\f\\n\\r\\t\\v。注意 Unicode 正则表达式会匹配全角空格符
    • 7.\S:匹配任何非空白字符。等价于 \^ \\f\\n\\r\\t\\v
    • 8.\t:匹配一个制表符。等价于 \x09 和 \cI
    • 9.\v:匹配一个垂直制表符。等价于 \x0b 和 \cK
  • 3.特殊字符
    • 1.所谓特殊字符,就是一些有特殊含义的字符,如上面说的 runoo*b 中的 ,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \,runo*ob 匹配字符串 runoob
    • 2.许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符"转义",即,将反斜杠字符\ 放在它们前面。下表列出了正则表达式中的特殊字符
    • 1. 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 也匹配 '\n' 或 '\r'。要匹配 字符本身,请使用
    • 1.( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。
    • 1.* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
    • 1.+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
    • 1... 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。
    • 1.[ 标记一个中括号表达式的开始。要匹配 [,请使用 [。
    • 1.? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。
    • 1.\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\' 匹配 "",而 '(' 则匹配 "("。
    • 1.^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 ^。
    • 1.{ 标记限定符表达式的开始。要匹配 {,请使用 {。
    • 1.| 指明两项之间的一个选择。要匹配 |,请使用 |
  • 4.限定符
    • 1.限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种
    • 1.* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于 {0,}。 尝试一下 >>
    • 1.+ 匹配前面的子表达式一次或多次。例如,zo+ 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 尝试一下 >>
    • 1.?
      匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 "do" 、 "does"、 "doxy" 中的 "do" 和 "does"。? 等价于 {0,1}。
    • 1.{n} n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 "Bob" 中的 o,但是能匹配 "food" 中的两个 o。 尝试一下 >>
    • 1.{n,} n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 "Bob" 中的 o,但能匹配 "foooood" 中的所有 o。o{1,} 等价于 o+。o{0,} 则等价于 o*。 尝试一下 >>
    • 1.{n,m} m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 "fooooood" 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格
      设置 0~99 的两位数,可以使用下面的表达式来至少指定一位但至多两位数字。/0-9{1,2}/
    • 匹配 1~99 的正整数表达式:/1-90-9?/、/1-90-9{0,1}/
    • 下面的表达式匹配从开始小于符号 (<) 到关闭 h1 标记的大于符号 (>) 之间的所有内容:/<.*>/
    • 通过在 *、+ 或 ? 限定符之后放置 ?,该表达式从"贪婪"表达式转换为"非贪婪"表达式或者最小匹配
  • 5.定位符
    • 定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。
    • 定位符用来描述字符串或单词的边界,^ 和 分别指字符串的开始与结束,\\b 描述单词的前或后边界,\\B 表示非单词边界 \^ 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,\^ 还会与 \\n 或 \\r 之后的位置匹配。 尝试一下 \>\> 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性, 还会与 \\n 或 \\r 之前的位置匹配。 尝试一下 \>\> \\b 匹配一个单词边界,即字与空格间的位置。 \\B 非单词边界匹配 注意:不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 \^\* 之类的表达式。 若要匹配一行文本开始处的文本,请在正则表达式的开始使用 \^ 字符。不要将 \^ 的这种用法与中括号表达式内的用法混淆。 若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 字符。
      若要在搜索章节标题时使用定位点,下面的正则表达式匹配一个章节标题,该标题只包含两个尾随数字,并且出现在行首:
      /^Chapter 1-90-9{0,1}/
      真正的章节标题不仅出现行的开始处,而且它还是该行中仅有的文本。它既出现在行首又出现在同一行的结尾。下面的表达式能确保指定的匹配只匹配章节而不匹配交叉引用。通过创建只匹配一行文本的开始和结尾的正则表达式,就可做到这一点。
      /^Chapter 1-90-9{0,1}$/
      匹配单词边界稍有不同,但向正则表达式添加了很重要的能力。单词边界是单词和空格之间的位置。非单词边界是任何其他位置。下面的表达式匹配单词 Chapter 的开头三个字符,因为这三个字符出现在单词边界后面:
      /\bCha/
      \b 字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项。如果它位于字符串的结尾,它在单词的结尾处查找匹配项。例如,下面的表达式匹配单词 Chapter 中的字符串 ter,因为它出现在单词边界的前面:
      /ter\b/
      下面的表达式匹配 Chapter 中的字符串 apt,但不匹配 aptitude 中的字符串 apt:
      /\Bapt/
      字符串 apt 出现在单词 Chapter 中的非单词边界处,但出现在单词 aptitude 中的单词边界处。对于 \B 非单词边界运算符,不可以匹配单词的开头或结尾,如果是下面的表达式,就不匹配 Chapter 中的 Cha:
      \BCha
  • 6.选择
    圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。
    () 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。
    但用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?: 放在第一个选项前来消除这种副作用。
    其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
  • 7.以下列出 ?=、?<=、?!、?<! 的使用区别
    exp1(?=exp2):查找 exp2 前面的 exp1
    (?<=exp2)exp1:查找 exp2 后面的 exp
    exp1(?!exp2):查找后面不是 exp2 的 exp1
    (?<!exp2)exp1:查找前面不是 exp2 的 exp1
  • 8.反向引用
    对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
    可以使用非捕获元字符 ?:、?= 或 ?! 来重写捕获,忽略对相关匹配的保存。
    反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例:
    Is is the cost of of gasoline going up up?
    上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子,而不必查找每个单词的重复出现,那该有多好。下面的正则表达式使用单个子表达式来实现这一点:
    实例
    查找重复的单词:
    var str = "Is is the cost of of gasoline going up up";
    var patt1 = /\b(a-z+) \1\b/igm;
    document.write(str.match(patt1));
    捕获的表达式,正如 a-z+ 指定的,包括一个或多个字母。正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。\1 指定第一个子匹配项。
    单词边界元字符确保只检测整个单词。否则,诸如 "is issued" 或 "this is" 之类的词组将不能正确地被此表达式识别。
    正则表达式后面的全局标记 g 指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。
    表达式的结尾处的不区分大小写 i 标记指定不区分大小写。
    多行标记 m 指定换行符的两边可能出现潜在的匹配。
    反向引用还可以将通用资源指示符 (URI) 分解为其组件。假定您想将下面的 URI 分解为协议(ftp、http 等等)、域地址和页/路径:
    https://www.runoob.com:80/html/html-tutorial.html
    第三行代码 str.match(patt1) 返回一个数组,实例中的数组包含 5 个元素,索引 0 对应的是整个字符串,索引 1 对应第一个匹配符(括号内),以此类推。
    第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。
    第二个括号子表达式捕获地址的域地址部分。子表达式匹配非 : 和 / 之后的一个或多个字符。
    第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。
    最后,第四个括号子表达式捕获 Web 地址指定的路径和 / 或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。
    将正则表达式应用到上面的 URI,各子匹配项包含下面的内容:
    第一个括号子表达式包含 https
    第二个括号子表达式包含 www.runoob.com
    第三个括号子表达式包含 :80
    第四个括号子表达式包含 /html/html-tutorial.html
相关推荐
HLC++19 分钟前
Linux的进程间通信
android·linux·服务器
groundhappy4 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕5 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫6 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生6 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.117 小时前
linux基础IO
linux·运维·服务器
BelongPanda9 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯9 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_7779983410 小时前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器
yunwei3710 小时前
eBPF 教程:检查 exec 后真正安装的可执行镜像
linux·开源