浅谈正则表达式匹配模式—贪婪模式

Posted 爬虫俱乐部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈正则表达式匹配模式—贪婪模式相关的知识,希望对你有一定的参考价值。

诸君安

又是stata学习时间

今天给大家介绍的是正则表达式

大家快点学起来

从此写程序快人一步


在stata中,正则表达式有两种最常见的匹配模式,分别为:贪婪模式和懒惰模式。正则表达式在字符串处理方面,能大大简化我们的程序,由于篇幅限制,我们将分为两篇推文给大家介绍这两种匹配模式,今天先给大家介绍一下贪婪模式。

在贪婪模式下,首先看整个字符串是否能与正则表达式匹配,如果匹配不成功,会去掉该字符串中的最后一个字符,并再次尝试匹配,如果匹配还是不成功,那么再去掉此时的最后一个字符。如果在去掉所有字符后仍然匹配不成功,那么会继续选取从第二个字符开始的整个字符串,重复上述的匹配过程。这个过程会一直重复,直到发现一个与正则表达式相匹配的字符串,或者全部尝试过后仍然匹配不出任何字符。用“贪婪”这个词,我们也可以形象地把这个模式解释为:首先吃掉所有的字符,然后一个一个吐出来,直到匹配成功。

在stata中,当使用除“{n}”之外的数量元字符时,会进入正则表达式匹配的贪婪模式。 例如,正则表达式re符合贪婪模式,对字符串“abc”进行匹配。

1、首先对整个字符串“abc”进行匹配;

2、如果匹配不上,去掉最后一个字符“c”,对“ab”进行匹配;

3、如果匹配不上,去掉最后一个字符“b”,对“a”进行匹配;

4、如果匹配不上,将“abc”第一个字符“a”去掉,对“bc”进行匹配;

5、如果匹配不上,去掉最后一个字符“c”,对“b”进行匹配;

6、如果匹配不上,去掉“bc”中的第一个字符“b”,对“c”进行匹配。


下面我们用一个例子来展示一下贪婪模式:

程序如下:

·clear

·set obs 10

·gen v = "A" + "B" * (_n - 1)

·gen v1 = ustrregexs(0) if ustrregexm(v, "AB*")

·gen v2 = ustrregexs(0) if ustrregexm(v, "AB+")

·gen v3 = ustrregexs(0) if ustrregexm(v, "AB?")

·gen v4 = ustrregexs(0) if ustrregexm(v, "AB{1,3}")

·gen v5 = ustrregexs(0) if ustrregexm(v, "AB{3,}")

·list, sep(0)

程序运行结果如下表所示:浅谈正则表达式匹配模式(一)—贪婪模式

首先,变量v1是正则表达式"AB*"的匹配结果,元字符“*”为数量元字符,它表示匹配前一个字符或子表达式任意次(这里即表示对字符“B”匹配0次或多次),我们以变量v中第一条观测值“A”和最后一条观测值“ABBBBBBBBB”为例。对于“A”,正则表达式“AB*”首先对整个字符串“A”进行匹配,匹配成功,这时候事实上对“B”匹配了0次;对于“ABBBBBBBBB”,正则表达式“AB*”首先岁整个字符串“ABBBBBBBBB”进行匹配,匹配成功,这里对字符“B”匹配了9次。正则表达式“AB*”的匹配结果可以为A、AB、ABB、ABBB、ABBBB...

v2是正则表达式“AB+”的匹配结果,与“AB*”不同的是这里必须对字符“B”至少匹配一次,因为元字符“+”表示对前一个字符或子表达式匹配一次或多次;所以对变量v中“A”进行匹配时,首先匹配整个字符串“A”,因为至少对“B”匹配一次,所以匹配不成功。其匹配结果可以为:AB、ABB、ABBB、ABBBB、ABBBBB...

v3是正则表达式“AB?”的匹配结果,元字符“?”表示对前一个字符或子表达式匹配0次或1次,我们还以“A”和“ABBBBBBBBB”为例。首先,对于字符串“A”进行匹配时,首先对整个字符串进行匹配,匹配成功,这时候对字符“B”匹配了0次;对“ABBBBBBBBB”进行匹配时,首先匹配整个字符串“ABBBBBBBBB”,因为“AB?”的匹配结果只可能是“A”、“AB”,因此匹配不成功,接着在贪婪模式下,首先去掉字符串的最后一个字符“B”,对“ABBBBBBBB”进行匹配,同样也是匹配不成功,直到去掉最后一个字符变为“AB”时,匹配成功,这时候对字符B匹配了1次,匹配结果为“AB”。

v4是正则表达式“AB{1,3}”的匹配结果,元字符“{n1,n2}”表示对前一个字符或子表达式匹配至少n1次,至多n2次。所以在对“A”进行匹配时,首先,把整个字符串“A”进行匹配,因为至少对字符“B”匹配1次,所以匹配不成功;对于“ABBBBBBBBB”,同样先对整个字符串“ABBBBBBBBB”进行匹配,由于对字符“B”至多匹配3次,所以匹配不成功,接着按贪婪模式的匹配法则,首先,去掉字符串末尾最后一个字符“B”,变为“ABBBBBBBB”,仍然匹配不成功,直到去掉字符“B”后变为“ABBB”时,匹配成功,这时候对字符“B”匹配了3次。

变量v5是正则表达式AB{3,}的匹配结果,元字符{n,}表示对前一个字符或子表达式匹配至少n次(此例中即表示至少匹配3次)。对“A”进行匹配时,因为至少对字符“B”匹配3次,所以匹配不成功;对于字符串“ABBBBBBBBB”匹配时,首先,匹配整个字符串“ABBBBBBBBB”,匹配成功,这时候对字符“B”匹配了9次。


浅谈正则表达式匹配模式(一)—贪婪模式

但是我们要注意一点,贪婪模式并不是说我们匹配出的就是整个字符串中所能匹配到的最长的子字符串,我们仔细分析贪婪模式的概念可以发现,它是先尝试匹配整个字符串,再从结尾处将一个一个字符剔除掉,这一特点有最高的优先权。也就是说在贪婪匹配模式下,匹配出的实际上是从尽可能靠近字符串开头的位置开始的,与正则表达式相匹配的最长的字符串。我们以下边一个例子为例:

clear

set obs 1

gen str v = "123a4567"

gen v1 = ustrregexs(0) if ustrregexm(v, "\d+")

list

浅谈正则表达式匹配模式(一)—贪婪模式

可以发现,在贪婪模式下匹配的并不是整个字符串中最长的子字符串“4567”,而是以靠近字符串开头位置开始,与正则表达式相匹配的最长字符串“123”。它的匹配过程为:首先,元字符“\d”是一个特殊元字符,表示0-9任意一个数字,等价于[0-9],正则表达式“\d+”则表示至少1个的连续数字,匹配时,先匹配整个字符串“123

a4567”,匹配不成功,然后去掉最后一个字符“7”,变为“123a456”,仍然匹配不成功,再去掉最后一个字符“6”...,直到去掉字符“a”,变为“123”,即匹配成功。



以上就是今天给大家分享的内容了,说得好就赏个铜板呗!有钱的捧个钱场,有人的捧个人场~。

                     文字编辑:梅洁瓷傲

技术总编:刘贝贝



往期推文推荐:

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.




关于我们

此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

欢迎关注爬虫俱乐部 

以上是关于浅谈正则表达式匹配模式—贪婪模式的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式贪婪与非贪婪模式

python正则表达式贪婪与非贪婪模式

js正则匹配总结

第11.9节 Python正则表达式的贪婪模式和非贪婪模式

正则表达式贪婪和非贪婪模式

JavaScript正则表达式模式匹配——贪婪模式和惰性模式