R中的正则表达式组捕获具有多个捕获组

Dan*_*son 87 regex r capture capture-group

在R中,是否可以从正则表达式匹配中提取组捕获?据我所知,没有一个grep,grepl,regexpr,gregexpr,sub,或gsub返回组拍摄.

我需要从编码的字符串中提取键值对:

\((.*?) :: (0\.[0-9]+)\)
Run Code Online (Sandbox Code Playgroud)

我总是可以做多个全匹配greps,或做一些外部(非R)处理,但我希望我能在R中完成所有操作.是否有一个功能或包提供这样的功能来执行此操作?

Ken*_*son 110

str_match()stringr包中,将做到这一点.它返回一个字符矩阵,匹配中的每个组都有一列(整个匹配一个):

> s = c("(sometext :: 0.1231313213)", "(moretext :: 0.111222)")
> str_match(s, "\\((.*?) :: (0\\.[0-9]+)\\)")
     [,1]                         [,2]       [,3]          
[1,] "(sometext :: 0.1231313213)" "sometext" "0.1231313213"
[2,] "(moretext :: 0.111222)"     "moretext" "0.111222"    
Run Code Online (Sandbox Code Playgroud)

  • 和 `str_match_all()` 匹配正则表达式中的所有组 (2认同)

Dav*_*ler 44

gsub从你的例子做到这一点:

gsub("\\((.*?) :: (0\\.[0-9]+)\\)","\\1 \\2", "(sometext :: 0.1231313213)")
[1] "sometext 0.1231313213"
Run Code Online (Sandbox Code Playgroud)

你需要双重转义引号中的\ s然后它们适用于正则表达式.

希望这可以帮助.

  • 大.R`gsub`手册页非常需要一个示例,显示您需要'\\ 1'来转义捕获组引用. (6认同)

小智 32

尝试regmatches()regexec():

regmatches("(sometext :: 0.1231313213)",regexec("\\((.*?) :: (0\\.[0-9]+)\\)","(sometext :: 0.1231313213)"))
[[1]]
[1] "(sometext :: 0.1231313213)" "sometext"                   "0.1231313213"
Run Code Online (Sandbox Code Playgroud)

  • 感谢vanilla R解决方案,并指出我以前从未见过的`regmatches' (3认同)

小智 18

gsub()可以执行此操作并仅返回捕获组:

但是,为了使其正常工作,您必须显式选择gsub()帮助中提到的捕获组外部的元素.

(...)未替换的字符向量'x'的元素将保持不变.

因此,如果要选择的文本位于某个字符串的中间,则在捕获组之前和之后添加.*应该只允许您返回它.

gsub(".*\\((.*?) :: (0\\.[0-9]+)\\).*","\\1 \\2", "(sometext :: 0.1231313213)") [1] "sometext 0.1231313213"


Art*_*sov 8

解决方案strcapture来自utils

x <- c("key1 :: 0.01",
       "key2 :: 0.02")
strcapture(pattern = "(.*) :: (0\\.[0-9]+)",
           x = x,
           proto = list(key = character(), value = double()))
#>    key value
#> 1 key1  0.01
#> 2 key2  0.02
Run Code Online (Sandbox Code Playgroud)

  • 这是做这样的事情的正确方法。允许使用 PCRE 并强制您明确预期的列类型和名称。 (2认同)