gsub, lookahead and lookbehind

3

我有一个字符串向量包含:

Number of source1.2_SPNB.txt
Number of source1.1_SPNB.txt
Number of source1.3_SPNB.txt

我需要在一个新的向量中提取"source1.1"、"source1.2"和"source1.3"。

根据这个,我尝试了:

gsub("(?<=of )(.*)(?=_)", "\\1", string.vector)

但是我收到了一个错误:

无效的正则表达式 '(?<=of )(.*)(?=_)',原因是“无效的正则表达式”

然后我尝试了:

gsub("(?<=of )(.*)(?=_)", "\\1", string.vector, perl = TRUE)

但是它返回了完全相同的字符串向量。

我做错了什么?

2个回答

10
有几个问题:
- 需要设置perl = TRUE才能使用前瞻/后顾 - 即使我们使用了这个,正则表达式实际上只是用自身替换所需的子字符串 -- 我们想要做的是匹配整个字符串(而不是使用零宽度的前瞻/后顾),然后将整个字符串替换为仅与捕获组匹配的部分。 - 可能只需要进行一次替换,所以应该使用sub而不是gsub。
修复这些问题后,我们得到:
sub(".*(source.*?)_.*", "\\1", string.vector)

1
我们可以匹配字符直到空格(.*\\s)或者(|)一个后面跟着其他字符的_,并用空白("")替换它。
gsub(".*\\s|_.*", "", string.vector)
#[1] "source1.2" "source1.1" "source1.3"

如果需要使用捕获组,则为:

或者如果我们需要使用捕获组,则

sub(".*\\sof\\s([^_]+).*", "\\1", string.vector)
#[1] "source1.2" "source1.1" "source1.3"

为了进行提取,最好使用 stringr 中的 str_extract 或者 base R 中的 regmatches/regexpr
regmatches(string.vector, regexpr("(?<=of )([^_]+)(?=_)", string.vector, perl = TRUE))
#[1] "source1.2" "source1.1" "source1.3"

数据

string.vector <- c("Number of source1.2_SPNB.txt", "Number of source1.1_SPNB.txt", 
             "Number of source1.3_SPNB.txt")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接