Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 非贪婪字符串正则表达式匹配_Regex_R_Stringr - Fatal编程技术网

Regex 非贪婪字符串正则表达式匹配

Regex 非贪婪字符串正则表达式匹配,regex,r,stringr,Regex,R,Stringr,我很确定我在这里遗漏了一些明显的东西,但我不能让R使用非贪婪正则表达式: > library(stringr) > str_match('xxx aaaab yyy', "a.*?b") [,1] [1,] "aaaab" 基本函数的行为方式相同: > regexpr('a.*?b', 'xxx aaaab yyy') [1] 5 attr(,"match.length") [1

我很确定我在这里遗漏了一些明显的东西,但我不能让R使用非贪婪正则表达式:

> library(stringr)
> str_match('xxx aaaab yyy', "a.*?b")                                         
     [,1]   
[1,] "aaaab"
基本函数的行为方式相同:

> regexpr('a.*?b', 'xxx aaaab yyy')
[1] 5
attr(,"match.length")
[1] 5
attr(,"useBytes")
[1] TRUE
我希望匹配的是
ab
,根据以下中的“贪婪”注释:

默认情况下,重复是贪婪的,因此使用最大可能的重复次数。 可以通过添加“最小值”将其更改为“最小值”?对于量词。(还有更多 允许近似匹配的量词:请参阅TRE文档。)

有人能解释一下发生了什么事吗

更新。疯狂的是,在其他一些情况下,非贪婪模式的行为与预期一致:

> str_match('xxx <a href="abc">link</a> yyy <h1>Header</h1>', '<a.*>')
     [,1]                                          
[1,] "<a href=\"abc\">link</a> yyy <h1>Header</h1>"
> str_match('xxx <a href="abc">link</a> yyy <h1>Header</h1>', '<a.*?>')
     [,1]              
[1,] "<a href=\"abc\">"
>str_匹配('xxx-yyy-Header','yyy-Header'
>str_匹配('xxx-yyy头','')
[,1]              
[1,] ""

这是一个很难理解的概念,所以我会尽我最大的努力……如果有点混乱,有人可以随意编辑和解释

匹配您的模式的表达式将从左到右搜索。是的,以下所有字符串
aaaaaab
aaab
aab
ab
都与您的模式匹配,但是
aaaab
最左边开始的字符串是返回的字符串

所以在这里,你的非贪婪模式不是很有用。也许这个例子可以帮助你更好地理解非贪婪模式的作用:

str_match('xxx aaaab yyy', "a.*?y") 
#      [,1]     
# [1,] "aaaab y"
这里所有的字符串
aaaab y
aaaab yy
aaaab yy
都与模式匹配并从相同的位置开始,但由于非贪婪模式,返回了第一个字符串


那么,如何捕捉最后一个
ab
?使用以下方法:

str_match('xxx aaaab yyy', ".*(a.*b)")
#      [,1]        [,2]
# [1,] "xxx aaaab" "ab"

它是如何工作的?通过在前面添加贪婪模式
*
,您现在正在强制进程将最后一个可能的
a
放入捕获的组中。

问题是匹配两个字符串之间的最短窗口。@flodel正确地提到正则表达式引擎正在从左到右解析字符串t、 因此,所有的匹配都是最左边的。贪婪和懒惰只适用于右边的边界:贪婪的量词将子字符串匹配到最右边的边界,而懒惰的量词将匹配到要跟随的子模式的第一次出现

请参见示例:

> library(stringr)
> str_extract('xxx aaaab yyy', "a[^ab]*b")
[1] "ab"
> str_extract('xxx aaa xxx aaa zzz', "xxx.*?zzz")
[1] "xxx aaa xxx aaa zzz"
> str_extract('xxx aaa xxx aaa zzz', "xxx(?:(?!xxx|zzz).)*zzz")
[1] "xxx aaa zzz"
第一个和第三个场景返回最短的窗口,第二个场景是当前问题的说明,但具有多字符输入

场景1.边界为单个字符

如果
a
b
是单个字符,则使用一个求反字符类找到最短的窗口。
a[^ab]*b
将很容易地从
a
抓取子字符串,直到下一个
b
,中间没有
a
s和
b
s

场景2.边界不是单个字符

在这些情况下,您可以使用可以进一步展开的字符。
xxx(?(!xxx | zzz)。*zzz
模式匹配
xxx
,然后是任何0+字符,而不是不是
xxx
zzz
字符序列(
(!xxx | zzz)的起始字符的换行字符
是一个负的前瞻,如果右边的子字符串与前瞻模式匹配,则匹配失败),然后是一个
zzz

这些匹配场景可以轻松地与基本R
regmatches
(使用支持lookaheads的PCRE regex风格)一起使用:

>x未列出(regmatches(x,gregexpr(“xxx(?(!xxx | zzz)。*zzz”,x,perl=TRUE)))
[1] “xxx aaa zzz”“xxx ccc zzz”

注意:当在base R中使用PCRE正则表达式,或在
str_extract
/
str_match
中使用ICU正则表达式时,
与换行符不匹配,要启用该行为,需要在模式开始处添加
(?s)
(内联DOTALL修饰符).

谢谢@floder-我完全忘记了它总是从左边开始匹配。人们已经讨论了很久了:
> x <- 'xxx aaa xxx aaa zzz xxx bbb xxx ccc zzz'
> unlist(regmatches(x, gregexpr("xxx(?:(?!xxx|zzz).)*zzz", x, perl = TRUE)))
[1] "xxx aaa zzz" "xxx ccc zzz"