将重置匹配标记 \K 与 stringr 函数一起使用

Using reset match token \K with stringr functions

我一直在回答这个问题,我遇到了一个奇怪的案例,我无法理解。

我们已将以下行复制到剪贴板:

Leading Men (Average American male: 5 feet 9.5 inches)

Dolph Lundgren — 6 feet 5 inches
John Cleese — 6 feet 5 inches

Leading Ladies (Average American female: 5 feet 4 inches)

Uma Thurman — 6 feet 0 inches
Brooke Shields — 6 feet 0 inches

我提供了下面的解决方案,它从 header 行中提取性别并用它填充下面的 lines/rows。这里的问题是它提取了单词 'Leading' 以及 "gender"。我希望能够使用 \K(重置匹配标记)来摆脱它,但这不起作用。

web.lines <- read.delim("clipboard", header = F) # reading data from clipboard

library(tidyverse)

web.lines %>% 
  mutate(gender = str_extract(V1, "Leading\s+\b(\w+)\b")) %>%
  fill(gender , .direction = "down") %>% 
  group_by(gender) %>% 
  slice(-1) %>% # removing the headers
  separate(V1, into = c("Name", "Height"), sep = " — ") 

#> # A tibble: 4 x 3
#> # Groups:   gender [2]
#>    Name                  Height             gender        
#>    <chr>                 <chr>              <chr>         
#> 1  Uma Thurman           6 feet 0 inches    Leading Ladies
#> 2  Brooke Shields        6 feet 0 inches    Leading Ladies
#> 3 Dolph Lundgren         6 feet 5 inches    Leading Men   
#> 4 John Cleese            6 feet 5 inches    Leading Men   

我试过的 Leading\s+\K\w+ 似乎在演示 https://regex101.com/r/pYaW7a/1 中有效,但在 str_extract.

中无效

在不支持它的 stringr 正则表达式函数中不需要 \K(请参阅 ICU regex syntax documentation), because you have str_match / str_match_all 函数。

PCRE、Perl、Onigmo、Python PyPi regex 和 Boost 正则表达式库支持的 \K match reset operator,因此也可通过 [=18= 在基础 R 正则表达式函数中使用] 参数,用于省略当前位置之前匹配的一些文本。使用捕获组可以达到相同的效果。 str_extractstr_extract_all 的问题在于它们不会在输出中保留捕获的子字符串。 str_match/str_match_all 在输出中保留捕获的子字符串。

查看 R 演示:

web.lines %>% 
  mutate(gender = str_match(V1, "Leading\s+(\w+)")[,2]) %>%
  fill(gender , .direction = "down") %>% 
  group_by(gender) %>% 
  slice(-1) %>% # removing the headers
  separate(V1, into = c("Name", "Height"), sep = " — ") 

输出:

# A tibble: 4 x 3
# Groups:   gender [2]
  Name           Height          gender
  <chr>          <chr>           <chr> 
1 Uma Thurman    6 feet 0 inches Ladies
2 Brooke Shields 6 feet 0 inches Ladies
3 Dolph Lundgren 6 feet 5 inches Men   
4 John Cleese    6 feet 5 inches Men  

这里,str_match(V1, "Leading\s+(\w+)")[,2]用于匹配和捕获一个或多个字符在Leading字和一个或多个空格之后,return 只是通过访问 [,2] 索引处的项目捕获的值。

注意这里的单词边界是多余的,在空格和单词 char 之间有一个隐式的单词边界,\w+ 之后的 \b 也隐式存在。