gsub返回超过正则表达式匹配

时间:2017-08-16 18:48:46

标签: r regex

我有这样的字符串

x = c(
"blahblah, blah blah, Plate 3, blah blah"
,
"blah blah, blah_Plate 2_blah, blah"
,
"blah, blah, blah blah, blah plate_3"
,
"blah blah, blah, plate 5.txt"
)

我想从所有这些文件名中获取板号,

所以我正在用

测试我的正则表达式匹配
 gsub("\\<Plate\\>.[0-9]","\\1",workdf_nums_plats$Bioplex_Files)

所以我最终可以做这样的事情

workdf_nums_plats$plat <- ifelse(grepl("\\<Plate\\>.[0-9]", workdf_nums_plats$Bioplex_Files), gsub("\\<Plate\\>.[0-9]","\\1",workdf_nums_plats$Bioplex_Files), NA)

我在返回时返回整个字符串,我尝试使用\ b来设置单词边界,但这并没有帮助。

任何建议都会非常感谢!

2 个答案:

答案 0 :(得分:5)

您需要在内部定义一个捕获组,并以不区分大小写的方式匹配plate,但不要作为整个单词,因为您需要在_之后匹配它(并且它是一个单词char,太):

workdf_nums_plats$plat <- sub(".*?Plate.([0-9]+).*","\\1", workdf_nums_plats$Bioplex_Files, ignore.case=TRUE)

请参阅下面的regex demo和R演示:

Bioplex_Files <- c("blahblah, blah blah, Plate 3, blah blah", "blah blah, blah_Plate 2_blah, blah", "blah, blah, blah blah, blah plate_3", "blah blah, blah, plate 5.txt")
plat <- sub(".*?Plate.([0-9]+).*","\\1", Bioplex_Files, ignore.case=TRUE)
plat
## => [1] "3" "2" "3" "5"

模式详情

  • .*? - 任意0个字符,尽可能少
  • Plate - plate子字符串(由于ignore.case=TRUE而不区分大小写)
  • . - 任何字符
  • ([0-9]+) - 第1组(来自替换模式的\1反向引用)匹配1位或更多位数
  • .* - 任何0+字符,直到字符串结尾。

如果您希望将Plate作为整个词匹配,则可以在Plate前添加(?:_|\b)模式,".*?(?:_|\\b)Plate.([0-9]+).*"。在这里,(?:_|\b)是一个非捕获组(即它不创建$2$1等),它匹配_或字边界。

另一种解决方案是匹配您需要的值,并且为此目的使用 stringr 很方便:

> str_extract(Bioplex_Files, "(?i)(?<=Plate.)[0-9]+")
[1] "3" "2" "3" "5"

这里,(?i)是一个不区分大小写的标志,(?<=Plate.)是一个肯定的后瞻,断言有Plate以及紧跟[0-9]+ - 1之后的任何字符或更多的数字(并且只有数字被复制,因为lookbehind模式是零长度断言,即它不会将文本添加到匹配值)。

答案 1 :(得分:3)

一种方法是使用regmatchesregexec来返回捕获的子表达式。

regmatches(test, regexec("[Pp]late.?([0-9]+)", test))
[[1]]
[1] "Plate 3" "3"      

[[2]]
[1] "Plate 2" "2"      

[[3]]
[1] "plate_3" "3"      

[[4]]
[1] "plate 5" "5" 

这里,[Pp]将匹配&#34; P&#34;或&#34; p&#34;,&#34;迟到&#34;从字面上来看,&#34;。&#34;匹配任何字符的0或1,&#34;()&#34;捕获所需的值,即&#34; [0-9] +&#34;,一个或多个数字。

由于这会返回一个列表,因此您希望使用sapply从每个列表项中提取第二个元素。

sapply(regmatches(test, regexec("[Pp]late.?([0-9]+)", test)), "[", 2)
[1] "3" "2" "3" "5"

数据

test <- 
c("blahblah, blah blah, Plate 3, blah blah", "blah blah, blah_Plate 2_blah, blah", 
"blah, blah, blah blah, blah plate_3", "blah blah, blah, plate 5.txt")