首页 > 其他分享 >正则表达式高级

正则表达式高级

时间:2024-08-12 09:27:57浏览次数:8  
标签:字符 量词 匹配 正则表达式 高级 模式 分组 字符串

正则表达式的三种模式【贪婪、勉强、侵占】

假定要分析的字符串是xfooxxxxxxfoo

模式.*foo (贪婪模式): 模式分为子模式p1(.*)和子模式p2(foo)两个部分. 其中p1中的量词匹配方式使用默认方式(贪婪型)。 匹配开始时,吃入所有字符xfooxxxxxx去匹配子模式p1。匹配成功,但这样以来就没有了字符串去匹配子模式p2。本轮匹配失败;第二轮:减少p1部分的匹配量,吐出最后一个字符, 把字符串分割成xfooxxxxxxfo和o两个子字符串s1和s2。 s1匹配p1, 但s2不匹配p2。本轮匹配失败;第三轮,再次减少p1部分匹配量,吐出两个字符, 字符串被分割成xfooxxxxxxfo和oo两部分。结果同上。第四轮,再次减少p1匹配量, 字符串分割成xfooxxxxxx和foo两个部分, 这次s1/s2分别和p1/p2匹配。停止尝试,返回匹配成功。
模式.*?foo (勉强模式): 最小匹配方式。第一次尝试匹配, p1由于是0或任意次,因此被忽略,用字符串去匹配p2,失败;第二次,读入第一个字符x, 尝试和p1匹配, 匹配成功; 字符串剩余部分fooxxxxxxfoo中前三个字符和p2也是匹配的. 因此, 停止尝试, 返回匹配成功。在这种模式下,如果对剩余字符串继续去寻找和模式相匹配的子字符串,还会找到字符串末尾的另一个xfoo,而在贪婪模式下,由于第一次匹配成功的子串就已经是所有字符,因此不存在第二个匹配子串。
模式.*+foo (侵占模式): 也叫占用模式。匹配开始时读入所有字符串, 和p1匹配成功, 但没有剩余字符串去和p2匹配。因此, 匹配失败。返回。

 

简单地说, 贪婪模式和占有模式相比, 贪婪模式会在只有部分匹配成功的条件下, 依次从多到少减少匹配成功部分模式的匹配数量, 将字符留给模式其他部分去匹配; 而占用模式则是占有所有能匹配成功部分, 绝不留给其他部分使用。

再看下面一个例子:贪婪模式与侵占模式的比较
正则:\w+[a-z]与\w++[a-z]
目标串:232hjdhfd7474$
分析:①\w+[a-z]:\w+属于贪婪模式,会一次性吃掉它所能吃掉的所有的字符,也就是子串232hjdhfd7474,此时[a-z]不能够找到匹配了,故\w+匹配的串会吐出一个字符4,但此时还是得不到匹配。反复的这样吐出回退,直到吐出字符d时,此时[a-z]能够匹配h,所以这时正则表达式会返回一次成功的匹配结果,为232hjdhfd
②\w++[a-z]:\w++属于侵占模式,它会一次性吃掉它所能够吃掉的所有字符,即子串232hjdhfd7474,而且不留给其他部分使用,故不会回退。此时[a-z]不能够找到匹配,所以此次匹配失败。在余下的子串中也找不到能匹配成功的子串。所以整个正则表达式是找不到匹配结果的!

 

量 词 种 类 意  义
贪婪 勉强 侵占
X? X?? X?+ 匹配 X 零次或一次
X* X*? X*+ 匹配 X 零次或多次
X+ X+? X++ 匹配 X 一次或多次
X{n} X{n}? X{n}+ 匹配 X n 次(这个应该不存在这几种模式,就是固定匹配n个)
X{n,} X{n,}? X{n,}+ 匹配 X 至少 n 次
X{n,m} X{n,m}? X{n,m}+ 匹配 X 至少 n 次,但不多于 m 次

 

正则表达式高级用法(分组与捕获)

分组的引入:

对于要重复单个字符,非常简单,直接在字符后卖弄加上限定符即可,例如 a+ 表示匹配1个或一个以上的a,a?表示匹配0个或1个a。这些限定符如下所示:

X ?

X ,一次或一次也没有

X *

X ,零次或多次

X +

X ,一次或多次

X { n }

X ,恰好 n 次

X { n ,}

X ,至少 n 次

X { n , m }

X ,至少 n 次,但是不超过 m 次

但是我们如果要对多个字符进行重复怎么办呢?此时我们就要用到分组,我们可以使用小括号"()"来指定要重复的子表达式,然后对这个子表达式进行重复,例如:(abc)? 表示0个或1个abc 这里一 个括号的表达式就表示一个分组 。

 分组可以分为两种形式,捕获组和非捕获组

 

分组就是对文本加括号以帮助执行某种操作,比如:

  • 在两种或更多可选模式中选择一个
  • 创建子模式
  • 捕获一个分组后以便之后向后引用
  • 对组合的模式使用某项操作(如量词)
  • 使用非捕获分组
  • 原子分组

选择操作
选择操作可在多个可选模式中匹配一个。例如,你想在"The rime of the Ancyent Mariner"中找出the出现过多少次,包括THE,The和the的形式。
若在RegExr上方文本框输入

(THE|The|the)

则看到所有the都被标亮。
可以使用选项来使分组更简短。例如:

(?i)

可以让模式不再区分大小写。所有上面带选择操作的模式可以写成

(?i)the

正则表达式中的选项

子模式
正则表达式中的子模式是指分组中的一个或多个分组。
例如:

(the|The|THE)
(t|T)h(e|eir)

括号对于子模式不是必须的。

\b[tT]h[ceinry]*\b

这个模式会匹配the或The还有thee,thy以及thence等单词。

  • \b匹配单词起始边界
  • [tT]是字符组,它匹配小写字母t或者大写字母T。可以看做是第一个子模式。
  • 然后匹配小写字母h
  • 第二个也就是最后一个子模式也表示为字符组[ceinry],后面量词*表示一个或多个
  • \b单词的结尾边界

捕获分组和后向引用
当一个模式的全部或者部分内容由一对括号分组时,它就对内容进行捕获并临时存储与内存中。可以通过后向引用重用捕获的内容。

\1

或者

$1

这里\1或$1引用的是第一个捕获的分组,而\2或$2引用的是第二个捕获的分组,以此类推。
命名分组
命名分组就是有名字的分组。
假如你要查找含有连续六个0的字符串:

000000

就可以用这个模式对连续三个0的分组命名:

(?<z>0{3})

然后你可以再使用该分组:

(?<z>0{3})\k<z>

或者

(?<z>0{3})\k'z'

或者

(?<z>0{3})\g{z}

命名分组的语法


非捕获分组
非捕获分组不会将内容存储在内存中。在你并不想引用分组的时候可以使用,因为没有存储内容,所以可以带来性能上的提升。

(the|The|THE)

这个分组不需要任何后向引用,所以可以写成非捕获分组:

(?:the|The|THE)

添加选项将其变为不区分大小写的模式:

(?i)(?:the)

也可以这样写:

(?:(?i)the)

最推荐的写法是这样的:

(?i:the)

原子分组
另一种非捕获分组是原子分组。
如果你使用的正则表达式引擎进行回溯操作,这种分组就可以将回溯操作关闭,但它只针对原子分组内的部分,而不针对整个正则表达式。

(?>the)

小结:

1.(THE|The|the),通过竖线|可以多个可选模式中匹配一个

2.括号()内的模式和字符组[]都可以看做一个分组

3.括号()内的分组会被捕获到内存中,使用\1或者$1后向引用

4.通过命名的分组可以用名字来后向引用

5.(?:the|The|THE)非捕获分组不会存在内存中,以提高性能

 

匹配unicode字符
有时候我们需要匹配ASCII范围之外的字符。

复制代码
"Qu’est-ce que la tolérance? c’est l’apanage de l’humanité. Nous sommes tous pétris de faiblesses et d’erreurs; pardonnons-nous réciproquement nos sottises, c’est la première loi de la nature." —Voltaire (1694–1778)

What is tolerance? It is the consequence of humanity. We are all formed of frailty and error;let us pardon reciprocally each other's folly--that is the first law of nature.
复制代码

我们将伏尔泰的名言输入到http://www.regexpal.com/中,然后输入正则表达式

\u00e9

\u之后跟着的十六进制值00e9,这里不区分大小写,00E9也可以,00E9对接十进制值233,在ASCII(0~127)之外。

注意在Regexpal中字母é,即小写e加上了一个重音符,被标亮了,这是因为在unicode中é就是U+00E9,所以\u00e9可以匹配到它。

Regexpal.com是javascript的正则表达式实现。javascript也允许使用以下语法实现:

\xe9

现在我们在其他正则引擎中试一下。http://regexhero.net/tester/是.NET编写的。

复制代码
古池
蛙飛び込む
水の音
    —芭蕉 (1644–1694)

At the ancient pond
a frog plunges into
the sound of water.
    —Basho (1644–1694)
复制代码

以上是日本诗人松尾芭蕉的俳句。
将其输入regexhero,然后输入正则

\u6c60

这是单词pond池塘所对应的日文字符的代码点。
另外,也可以匹配一下长破折号

\u2014

或短破折号

\u2013

用八进制数匹配字符
在正则中,用八进制数就是在反斜线后加三位数字。
比如

\351

等同于

\u00e9

匹配控制字符
代码库的ASCII.txt里是所有ASCII字符,一个字符一行,一共128行。
在正则表达式中,像这样来指定一个控制字符:

\cx

其中x就是你想匹配的控制字符
匹配unicode和其他字符

 

正则表达式入门(七)量词

  复制代码
1
22
333
4444
55555
666666
7777777
88888888
999999999
0000000000
复制代码

将排列成直角三角形的数字粘贴到程序中。
贪心,懒惰和占有
量词本身是贪心的,贪心的量词会首先匹配整个字符串。尝试匹配时,它会选定尽可能多的内容,也就是整个输入。量词首次尝试匹配整个字符串,如果失败则回退一个字符后再尝试,这个过程叫做回溯。它每次回退一个字符,知道找到匹配内容或者没有字符尝试为止。
懒惰的意思就是它从目标的起始位置开始尝试寻找匹配,每次检查字符串的一个字符。最后它会尝试匹配整个字符串。要使一个量词成为懒惰的,必须在普通量词后添加一个问好?
占有量词会覆盖整个目标然后尝试寻找匹配内容,但它只尝试一次,不会回溯。占有量词就是在普通量词之后添加一个加号。

用*,+和?进行匹配
在工具中输入

.*

它会以贪心的方式匹配文本中的所有字符。*匹配任何字符零次或多次。
贪心的量词


匹配特定次数
使用花括号可以限制某个模式在某个范围内匹配的次数,未修饰的量词是贪心量词。
例如:

7{1}

会匹配第一次出现的7,要匹配一个或多个7,只需要加一个逗号:

7{1,}

所以,7+其实和7{1,}是一样的。
那么,7*其实和7{0,}是一样的。
最后,7?其实和7{0,1}是一样的
范围语法

懒惰量词

在工具中用?来匹配零个或一个5

5?

再加一个?使量词编程懒惰的

5??

现在它不匹配任何内容了,因为现在的模式是懒惰的。它不会强制匹配第一个5,懒惰的基本特性就是匹配尽可能少的字符。

试一下匹配零个或多个

5*?

它也不匹配任何内容,因为它选择匹配最少的次数,零次。

试一下匹配一个或多个

5+?

它匹配了一个5,它选择了最少的次数,一次。

使用m和n的方式也是一样的

5{2,5}?

它将匹配2个5,而不是5个。

如果你想匹配最少而不是最多的数目,就使用懒惰量词。

占有量词

占有式量词很像贪心式量词,它会选择尽可能多的内容,但它不回溯。它不会放弃找到的内容,它很自私。优点是速度快。

我们先匹配以零开头的多个零,然后再匹配以零结尾的多个零。

0.*+

所有零都被标亮了。

.*+0

不匹配任何内容。因为它没有回溯,一下子选定了所有的输入,不再回来查看。它一下子没有在结尾找到零,也不知该从哪里找起。

 

环视是一种非捕获分组,它根据某个模式之前或之后的内容匹配其他模式。环视也称为零宽度断言。

环视包括:

  • 正前瞻
  • 反前瞻
  • 正后顾
  • 反后顾
复制代码
THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.

ARGUMENT.

How a Ship having passed the Line was driven by Storms to the cold
Country towards the South Pole; and how from thence she made her course
to the tropical Latitude of the Great Pacific Ocean; and of the strange
things that befell; and in what manner the Ancyent Marinere came back to
his own Country.

I.

1      It is an ancyent Marinere,
2        And he stoppeth one of three:
3      "By thy long grey beard and thy glittering eye
4 "Now wherefore stoppest me?
复制代码

正前瞻

假设要匹配单词ancyent,且要求紧跟的单词是marinere,可以使用正前瞻。

(?i)ancyent(?=marinere)

(?i)不区分大小写,所以现在就是在每一行中寻找后跟marinere的单词ancyent。

反前瞻

反前瞻是正前瞻的取反操作。说明要在需要匹配的模式后找不到给定的前瞻内容。

(?i)ancyent(?!marinere)

这里,正前瞻的=变成了反前瞻的!。

正后顾

正后顾会查看前面的内容,和正前瞻的方向相反。

(?i)(?<=ancyent)marinere

反后顾

(?i)(?<!ancyent)marinere

 

 

 

标签:字符,量词,匹配,正则表达式,高级,模式,分组,字符串
From: https://www.cnblogs.com/596014054-yangdongsheng/p/10246774.html

相关文章

  • 装饰器模式的魔法:Python高级应用全解析
    装饰器模式的魔法:Python高级应用全解析在Python的世界里,装饰器模式以其独特的魅力,成为了函数式编程的一颗璀璨明珠。它不仅能够增强函数的功能,还能在不修改原有代码的前提下,注入新的活力。本文将深入探讨Python中的装饰器模式,从基础到高级,一探其究竟。装饰器模式的奥义装......
  • 人工智能算法工程师(高级)课程11-自然语言处理之NLP的语言模型-seq2seq模型,seq+注意
    大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程11-自然语言处理之NLP的语言模型-seq2seq模型,seq+注意力,word2vec与代码详解。本课程面向高级人工智能算法工程师,深入讲解自然语言处理(NLP)中的关键语言模型技术,包括seq2seq模型及其增强版加入注意力机制......
  • C语言之高级数据讲解
    目录1高级数据1.1结构1.2从数组到链表1.3抽象数据类型(ADT)1.3.1讲解1.3.2实践1.4队列ADT1.4.1讲解1.4.2用队列进行模拟1.5链表和数组1.6二叉查找树1.6.1讲解1.6.2实践1高级数据1.1结构在开始编写代码之前,要做很多程序设计方面的决定。数组表示相对不灵活,在运行......
  • C--密码学高级教程-全-
    C#密码学高级教程(全)原文:ProCryptographyandCryptanalysis协议:CCBY-NC-SA4.0一、密码学基础介绍密码学的历史很长,也很有趣。完整的密码学非技术参考,推荐破译者[1]。这本书介绍了从大约4000年前埃及人首次使用密码学到近代历史,当时密码学在两次世界大战的结局中......
  • 提高效率:Linux 正则表达式实用技巧
    目录前言匹配符号用法讲解“.”用法[]用法“*”用法“.*”用法“\?”用法“\+”用法“\\{n\\}”用法\\{m,n\\}用法锚点符号“^”用法“$”用法“^$”用法或|用法前言在Linux系统中,正则表达式(RegularExpressions,简称regex)是一个强大的工具,广泛应......
  • Python字典的高级用法
    一、collections中defaultdict的使用1.字典的键映射多个值将下面的列表转成字典l=[('a',2),('b',3),('a',1),('b',4),('a',3),('a',1),('b',3)]一个字典就是一个键对应一个单值的映射,而上面的列表中有相同键。如果你想要一个键映射多个值,那么就需要将这多个值放到另外......
  • 探索-C--高级特性-全-
    探索C#高级特性(全)原文:ExploringAdvancedFeaturesinC#协议:CCBY-NC-SA4.0一、受关注的C#7C#7于2017年3月发布,是VisualStudio2017发布的一部分。如上所述。NETBlog中,C#7专注于数据消费、简化代码和提高性能。C#7最大的特点是元组和模式匹配。使用元......
  • MySQL高级知识-----Explain
    Explainexplain(执行计划),使用explain关键字可以模拟优化器执行sql查询语句,从而知道MySQL是如何处理sql语句。explain主要用于分析查询语句或表结构的性能瓶颈。1.explain的作用通过explain+sql语句可以知道如下内容:1.表的读取顺序。(对应id)......
  • 在 Windows 上使用 LCX(Local Channel eXchange)来进行本地和远程转发,此大纲旨在提供顶
    LCX(LocalChanneleXchange)通常指的是一种用于网络协议中的本地和远程转发技术。如果你在谈论的是与LCX相关的网络配置,它可能涉及不同的上下文,例如在通信协议或网络交换中。本地和远程转发的基本概念:本地转发(LocalForwarding):本地转发将本地计算机上的一个端口转发到......
  • 002.Vue3入门,使用模板语法的一些高级功能
    1、代码如下:<template><h3>模板语法</h3><p>{{msg}}</p><p>{{msg_cn}}</p><p>{{number+1}}</p><p>{{ok?'Yes':'No'}}</p><p>{{message.split("......