我正在尝试使用str_extract_all
包中的stringr
从R中的某些文本中提取值,我想使用perl的regexps (?:...)
中的非匹配组来提取并在一行中清除相关值。
运行此代码时:
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]+'))
我想得到这个结果:
[[1]]
[1] "4" "46"
但我明白了:
[[1]]
[1] "WIDTH 4" "WIDTH 46"
我做错了什么?
答案 0 :(得分:5)
正则表达式仍匹配WIDTH
- 它只是没有将它放入捕获组。你的正则表达式相当于
WIDTH\s+[0-9]+
您的代码会提取正则表达式匹配的整个子字符串。 (非)捕获组不会改变它。
您可以使用lookbehind声明某个字符串位于当前位置之前,而不将其包含在匹配的子字符串中:
(?<=WIDTH\s)[0-9]+
根据确切的正则表达式引擎,您不能在lookbehind中使用可变长度模式。还有另一种形式可以允许:
WIDTH\s+\K[0-9]+
答案 1 :(得分:2)
perl零宽度正则表达式是错误的。
以下是不需要perl正则表达式的解决方案:
sub("WIDTH\\s+", "", str_extract_all(x, 'WIDTH\\s+[0-9]+')[[1]])
或更简单:
library(gsubfn)
strapplyc(x, "WIDTH\\s+(\\d+)")
此外,如果我们希望将结果返回为数字,则可以使用:
strapply(x, "WIDTH\\s+(\\d+)", as.numeric)