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

 

作者 dmxsp

发表回复

您的电子邮箱地址不会被公开。