stringr::str_view() 和 tidyr::extract() 正则表达式的区别?

stringr::str_view() and tidyr::extract() regular expression differences?

我正在尝试使用 tidyr::extract() 从 table 中提取具有多个 key:value 对的列。我已经使用 stringr::str_view() 微调了我的正则表达式,但我遇到了意外行为 - tidyr::extract() 似乎与 stringr::str_view() 匹配的字符串不同。

如何修改 tidyr::extract() 的使用以获得我想要的行为?

示例:

library(tidyverse)
library(stringr)

df <- as_data_frame('protein_id "ENSP00000260585.7"; tag "basic"; tag "appris_principal"; tag "CCDS"; tag "seleno"; ccdsid "CCDS46240.1"; havana_gene "OTTHUMG00000151931.3"; havana_transcript "OTTHUMT00000324484.3";')

# match I expect: 'tag "basic"; tag "appris_principal"; tag "CCDS"; tag "seleno"; '
str_view(df$value, '(tag "(?:.+?)"; +)+')

# match I get: 'tag \"seleno\"; '
(df %>% extract(value, "tags", '(tag "(?:.+?)"; +)+', remove = FALSE))$tags

我想将 4 个标签 key:value 的集合提取到名为标签的新列中,然后我将对其进行整理。但是当我只是从 extract 中得到 4 对中的 1 对时,这很难!

我认为我上面的评论很清楚,但以防万一翻译我的正则表达式来描述我的意图有帮助,我将其解释为:我想匹配 'tag "(0 or more chars, lazy evaluation)";(optional space)' 的 0 次或多次重复(贪婪评估)。

啊——这与贪婪与懒惰的取舍以及 extract() "turns each [capture] group into a new column" 的事实有关。所以我只需要一个捕获组:

> (df %>% extract(value, "tags", '((?:tag "(?:.+?)"; +)+)', remove = FALSE))$tags

[1] "tag \"basic\"; tag \"appris_principal\"; tag \"CCDS\"; tag \"seleno\"; "

正则表达式...