str_extract_all返回不匹配的组

aje*_*eck 2 regex perl r stringr

我正在尝试str_extract_allstringr包中使用R中的某些文本提取值,并且我想使用perl的regexp中的非匹配组(?:...)来提取和清除一行中的相关值.

运行此代码时:

library(stringr)

## Example string.
## Not the real string, but I get the same results with this one.
x <- 'WIDTH 4\nsome text that should not be matched.\n\nWIDTH   46 some text.'

## extract values
str_extract_all(x, perl('(?:WIDTH\\s+)[0-9]+'))
Run Code Online (Sandbox Code Playgroud)

我想得到这个结果:

[[1]]
[1] "4"    "46"
Run Code Online (Sandbox Code Playgroud)

但我明白了:

[[1]]
[1] "WIDTH 4"    "WIDTH   46"
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

amo*_*mon 5

正则表达式仍然匹配WIDTH- 它只是没有把它放入捕获组.你的正则表达式相当于

WIDTH\s+[0-9]+
Run Code Online (Sandbox Code Playgroud)

您的代码提取正则表达式匹配的整个子字符串.(非)捕获组不会更改此设置.

您可以使用lookbehind断言某个字符串位于当前位置之前,而不将其包含在匹配的子字符串中:

(?<=WIDTH\s)[0-9]+
Run Code Online (Sandbox Code Playgroud)

根据确切的正则表达式引擎,您不能在lookbehind中使用可变长度模式.还有另一种形式可以允许:

WIDTH\s+\K[0-9]+
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是正确的,你只需要在最终表达式中转义反斜杠\所以它变为`WIDTH \\ s + \\ K [0-9] +`,你可以在线测试[这里](http:// pbil .univ-lyon1.fr/Rweb /)你会发现它给出了正确的输出. (2认同)