1.正则表达式概述
正则表达式(Regular Expression)是一种用于匹配、查找和替换文本中特定模式的强大工具。它在许多编程语言和文本处理工具中都有广泛应用,以下是关于它的详细介绍:
基本概念
字符
正则表达式由普通字符(如字母、数字等)和特殊字符(具有特定含义的符号)组成。普通字符按照其字面意义进行匹配,例如在正则表达式 “abc” 中,就会精确匹配文本中的 “abc” 这三个连续字符。
普通字符:如字母、数字、下划线等,直接匹配自身。例如,“a” 将匹配文本中的 “a” 字符。
特殊字符:具有特定含义的字符,如 “.”“*”“+”“?”“\” 等。
元字符
是具有特殊含义的字符,比如 “.” 可以匹配除换行符以外的任意单个字符;“*” 表示前面的字符可以出现零次或多次等。常见的元字符还有 “+”(前面的字符出现一次或多次)、“?”(前面的字符出现零次或一次)等。
元字符
“.”:匹配任意单个字符,除了换行符。
“\d”:匹配一个数字字符。
“\w”:匹配一个字母、数字或下划线字符。
“\s”:匹配一个空白字符,包括空格、制表符、换行符等。
“^”:表示匹配行的开头。
“$”:表示匹配行的结尾。
^$:空行
\D:匹配任何非数字字符。
\W:匹配任何非字母数字字符。
\S:匹配任何非空白字符。
\b:匹配单词边界。
\B:匹配非单词边界。
量词
“*”:匹配前面的元素零次或多次。
“+”:匹配前面的元素一次或多次。
“?”:匹配前面的元素零次或一次。
“{n}”:匹配前面的元素恰好 n 次。
“{n,}”:匹配前面的元素至少 n 次。
“{n,m}”:匹配前面的元素至少 n 次,至多 m 次。
0{2,5}:限定数字 “0” 出现的次数在 2 到 5 次之间,在字符串 “000”、“0000”、“00000” 中都能匹配成功,而在 “0” 或者 “000000” 等情况下就可能匹配失败(具体取决于使用场景和其他匹配条件
[abc]{2}可以匹配 “aa”、“bb”、“cc”,因为它表示匹配 “a”、“b” 或 “c” 重复两次的情况。
a{1,3}b可以匹配 “ab”、“aab” 或 “aaab”,因为它表示 “a” 重复一到三次,后面跟着一个 “b”
字符集
[abc] 匹配包含在方括号内的任意一个字符(如 a 或 b 或 c)。
[^abc] 匹配不在方括号内的任意一个字符。
[a-z] 匹配从 a 到 z 范围内的任意一个字母。
[A-Z] 匹配从 A 到 Z 范围内的任意一个字母。
[0-9] 匹配从 0 到 9 范围内的任意一个数字。
{} 用于指定前一个元素的出现次数,可以是精确匹配、至少匹配或范围匹配。
[] 用于定义一个字符类,匹配方括号内的任意一个字符,可以包括范围和否定。
分组与引用
(ab) 将 “ab” 视为一个整体进行匹配。
\1, \2 等等,引用之前捕获的组。
选择
a|b 匹配 a 或者 b。
示例
a.b 可以匹配 “acb”,”a2b”,”a b” 等等,但不能匹配 “ab”。
^a 只能匹配以 ‘a’ 开头的字符串。
b$ 只能匹配以 ‘b’ 结尾的字符串。
colou?r 可以匹配 “color” 或 “colour”。
[0-9]{3} 匹配三个连续的数字,例如 “123”。
非贪婪匹配
默认情况下,量词 *, +, {n,}, {n,m} 是贪婪的,意味着它们会尽可能多地匹配字符。如果在这些量词后面加上 ?,它们就会变成非贪婪模式,即尽可能少地匹配字符。
转义字符
\ 用于转义特殊字符,使其失去特殊意义。例如,要匹配点号 .,需要写成 \.。
正则表达式非常强大,但也可能因为过于复杂而难以理解和维护。因此,在编写正则表达式时,清晰性和简洁性是非常重要的。如果你有特定的需求或问题,可以告诉我,我会尽力提供帮助。
常用语法
字符类:可以用方括号 “[]” 来定义字符类,它表示匹配方括号内的任意一个字符。例如 “[abc]” 能匹配 “a”“b” 或者 “c”。还可以使用范围表示,如 “[a-z]” 可匹配任意小写字母。
量词:用于指定前面的字符或字符组出现的次数。除了前面提到的 “*”“+”“?”,还有 “{n}”(前面的字符恰好出现 n 次)、“{n,}”(前面的字符至少出现 n 次)、“{n,m}”(前面的字符出现次数在 n 到 m 之间)等。
分组:用小括号 “()” 可以将字符或字符组进行分组,以便对分组内的内容进行整体操作,比如重复、获取匹配的子串等。
应用场景
文本验证
在用户注册登录时验证输入的邮箱地址、电话号码等格式是否正确。例如,验证邮箱的正则表达式可能是 “^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$”,它会检查输入的字符串是否符合常见的邮箱格式。
文本搜索与替换
在一篇长篇文档中快速查找特定模式的文本并进行替换。比如要将文档中所有的数字替换成 “*”,就可以使用合适的正则表达式来定位数字然后进行替换操作。
数据提取
从大量文本数据中提取出符合特定模式的信息。比如从网页源代码中提取所有的超链接地址等。
正则表达式的应用场景
文本搜索和替换
在文本编辑器中,可以使用正则表达式快速查找特定模式的文本,并进行替换操作。例如,将所有包含 “abc” 的字符串替换为 “def”。
数据验证
在表单验证中,正则表达式可以用来验证用户输入的邮箱地址、电话号码、密码等是否符合特定的格式要求。
日志分析
通过正则表达式可以从大量的日志文件中提取出有用的信息,如特定的错误消息、访问 IP 地址等。
编程语言中的应用
许多编程语言都支持正则表达式,如 Python、Java、JavaScript 等。可以在程序中使用正则表达式来处理文本数据。
2.正则和通配符区别
正则表达式(Regular Expression, 简称 regex 或 regexp)和通配符(wildcard)都是用于模式匹配的工具,但它们在功能、语法和使用场景上有显著的区别。下面详细对比这两种模式匹配工具
正则表达式
功能强大
正则表达式可以实现非常复杂的文本匹配、查找、替换等操作。它支持各种字符类、量词、断言等高级特性。
灵活性高
可以用来匹配复杂的模式,如电子邮件地址、电话号码、URL等。
广泛使用
几乎所有的编程语言都支持正则表达式的使用,它在文本处理、数据验证等领域有着广泛的应用。
通配符
简单直观
通配符通常只包含有限的几个符号,如星号(*
)代表任意数量的字符,问号(?
)代表单个字符,这些符号易于理解和使用。
特定用途
通配符主要用于文件名匹配,在命令行界面(如DOS、Unix/Linux shell)中常见,用于指定一组文件名。
语法简单
由于功能较为单一,通配符的语法也相对简单,容易上手。
语法
正则表达式
字符类
[abc] 匹配 a、b 或 c 中的任何一个字符。
[a-z] 匹配任何一个小写字母。
[0-9] 匹配任何一个数字。
预定义字符类:
\d 匹配任何一个数字。
\w 匹配任何一个字母数字字符。
\s 匹配任何一个空白字符。
量词:
* 匹配前面的元素零次或多次。
+ 匹配前面的元素一次或多次。
? 匹配前面的元素零次或一次。
{n} 匹配前面的元素恰好 n 次。
{n,} 匹配前面的元素至少 n 次。
{n,m} 匹配前面的元素至少 n 次,至多 m 次。
定位符
^ 匹配字符串的开始。
$ 匹配字符串的结束。
\b 匹配单词边界。
\B 匹配非单词边界。
分组和引用
() 用于分组。
\1, \2, … 用于引用前面的分组。
选择:
| 表示“或”,匹配左边或右边的表达式。
通配符
星号 (*):匹配任意数量的任意字符。
问号 (?):匹配单个任意字符。
方括号 ([]):匹配括号内的任意一个字符。
[abc] 匹配 a、b 或 c 中的任何一个字符。
[a-z] 匹配任何一个小写字母。
[0-9] 匹配任何一个数字。
范围和否定:
[^abc] 匹配除 a、b、c 之外的任何字符。
[!abc] 同上,某些系统中使用 ! 表示否定。
使用场景
正则表达式
文本处理:在编程中对用户输入的数据进行格式校验,如验证电子邮件地址、电话号码等。
搜索和替换:在文本编辑器中进行复杂的搜索和替换操作。
数据提取:从日志文件或其他文本数据中提取特定信息。
通配符
文件名匹配:在命令行界面中用于指定一组文件名,如 *.txt 匹配所有扩展名为 .txt 的文件。
路径匹配:在文件系统中用于匹配目录路径,如 *./*/*.jpg 匹配所有子目录中的 .jpg 文件。
匹配精度
正则表达式:
能实现高度精确匹配。可对文本中字符位置、出现次数、组合方式等进行细致规定。
不仅能匹配字符本身,还能匹配满足特定条件的字符串集合,如以某特定字符串开头且以另一特定字符串结尾,中间含特定格式字符的文本等复杂情况。
例如,“\d {3}-\d {3}-\d {4}” 可精确匹配美国电话号码格式(三个数字 – 三个数字 – 四个数字),通过量词 “{n}” 精准限定数字出现次数。
通配符:
匹配较为粗放。主要侧重于对文件名、简单文本片段等进行基于字符数量和类型的大致匹配。
比如在文件系统搜索中,通配符可快速找到符合扩展名或文件名部分大致特征的文件,但难以像正则表达式那样对文件内容中复杂文本模式进行精细匹配。
例如,“*.jpg” 可找到所有以 “.jpg” 为扩展名的文件,但无法确定文件内容中是否存在特定格式的文本。
3.perl正则
Perl语言以其强大的文本处理能力而闻名,其中正则表达式是其核心特性之一。Perl的正则表达式功能非常强大,基本上是常用语言中最强大的,很多语言设计正则式支持的时候都参考Perl的正则表达式。Perl的正则表达式有三种形式,分别是匹配、替换和转化
基本语法
在 Perl 中,正则表达式通常用 m// 进行匹配,用 s/// 进行替换。如果不指定 m,也可以直接使用 // 进行匹配
常用字符
点 .:匹配任何单个字符(除了换行符)。
星号 *:匹配前一个字符零次或多次。
加号 +:匹配前一个字符一次或多次。
问号 ?:匹配前一个字符零次或一次。
花括号 {}:指定前一个字符的出现次数。
方括号 []:定义一个字符类。
脱字符 ^:匹配行首或否定字符类。
美元符号 $:匹配行尾。
竖线 |:逻辑或。
圆括号 ():分组和捕获
i 忽略模式中的大小写
m 多行模式
o 仅赋值一次
s 单行模式,”.” 匹配 “\n”(默认不匹配)
x 忽略模式中的空白
g 全局匹配
cg 全局匹配失败后,允许再次查找匹配串
正则表达式变量
Perl处理完后会给匹配到的值存在三个特殊变量名:
$:匹配部分的前一部分字符串
$&:匹配的字符串
$’:还没有匹配的剩余字符串
Perl中的修饰符分为两大类:模式修饰符和匹配修饰符。
模式修饰符
/i:不区分大小写进行匹配。
/m:多行匹配,使得 ^ 和 $ 匹配每一行的开始和结束。
/s:单行匹配,使得点号 . 匹配所有字符,包括换行符。
/x:扩展模式,允许在正则表达式中加入空格和注释,提高可读性。
匹配修饰符
/g:全局匹配,找到所有匹配项,而不是仅第一个。
/c:匹配时不捕获分组,提高效率。
/l:从匹配结果中删除反向引用。
/p:执行正则表达式时,保留最后的匹配结果。
零宽断言
(?=…):正向肯定预查,在任何匹配 … 的字符串开始处匹配。
(?!…):正向否定预查,在任何不匹配 … 的字符串开始处匹配。
(?<=…):反向肯定预查,在任何匹配 … 的字符串结束处匹配。
(?<!…):反向否定预查,在任何不匹配 … 的字符串结束处匹配。
示例
1
[root@shell /server/scripts]$ cat perl.sh
#!/usr/bin/perl
$bar = “I am runoob site. welcome to runoob site.”;
if ($bar =~ /run/) {
print “第一次匹配\n”;
} else {
print “第一次不匹配\n”;
}
$bar = “run”;
if ($bar =~ /run/) {
print “第二次匹配\n”;
} else {
print “第二次不匹配\n”;
}
[root@shell /server/scripts]$ perl perl.sh
第一次匹配
第二次匹配
2
[root@shell /server/scripts]$ cat perl1.sh
#!/usr/bin/perl
use strict;
use warnings;
my $text = “The quick brown fox jumps over the lazy dog.”;
# 正向肯定预查
if ($text =~ /fox(?= jumps)/) {
print “Found ‘fox’ followed by ‘jumps’.\n”;
}
# 正向否定预查
if ($text =~ /fox(?! jumps)/) {
print “Found ‘fox’ not followed by ‘jumps’.\n”;
}
# 反向肯定预查
if ($text =~ /(?<=The )quick/) {
print “Found ‘quick’ preceded by ‘The ‘.\n”;
}
# 反向否定预查
if ($text =~ /(?<!The )quick/) {
print “Found ‘quick’ not preceded by ‘The ‘.\n”;
}
[root@shell /server/scripts]$ perl perl1.sh
Found ‘fox’ followed by ‘jumps’.
Found ‘quick’ preceded by ‘The ‘.
3.非捕获组:用于应用量词,但不存储匹配的文本
[root@shell /server/scripts]$ cat perl2.sh
$text = “The year 2023 is not far away.”;
@matches = ($text =~ /(?:\d+)/g);
print “Year found: @matches\n”;
[root@shell /server/scripts]$ perl perl2.sh
Year found: 2023
4.后向和前向断言:断言允许您指定必须在字符串的某个位置之前或之后的条件,但不会消耗字符
[root@shell /server/scripts]$ cat perl3.sh
$text = “We have 2 apples and 3 bananas.”;
if ($text =~ /(\d+) apples/) {
print “We have “. $1. ” apples.\n”;
}
[root@shell /server/scripts]$ perl perl3.sh
We have 2 apples.
5.正向后瞻:允许您指定某个模式后面必须跟随的另一个模式
[root@shell /server/scripts]$ cat perl4.sh
$text = “Please press F5 to refresh.”;
if ($text =~ /(F5)(?= to refresh)/) {
print “Press “. $1. ” to refresh.\n”;
}
[root@shell /server/scripts]$ perl perl4.sh
Press F5 to refresh.
6.负向先行断言:用于指定某个模式前面不能出现的模式
[root@shell /server/scripts]$ cat perl5.sh
$text = “Do not press F12.”;
if ($text =~ /(F12)(?! to refresh)/) {
print “Do not press “. $1. “.\n”;
}
[root@shell /server/scripts]$ perl perl5.sh
Do not press F12.
7.使用lookbehind进行断言:允许你在字符串中向前查看,确保某个模式之前不出现
[root@shell /server/scripts]$ cat perl6.sh
$text = “The date is 12/31/2023.”;
if ($text =~ /(?<!\w)(\d{1,2}\/\d{1,2}\/\d{4})/) {
print “Date found: $1\n”;
}
[root@shell /server/scripts]$ perl perl6.sh
Date found: 12/31/2023
8.假设我们想找到所有不在单词内部的 “q”
[root@shell /server/scripts]$ cat perl7.sh
#!/usr/bin/perl
use strict;
use warnings;
my $text = “The quick brown fox jumps over the lazy dog.”;
# 使用负向后瞻断言找到不在单词内部的 “q”
while ($text =~ /(?<!\w)q/g) {
print “Found ‘q’ not preceded by a word character at position: “, pos($text), “\n”;
}
[root@shell /server/scripts]$ perl perl7.sh
Found ‘q’ not preceded by a word character at position: 5