Извлечь три группы: между вторым и предпоследним, между предпоследним и последним и после последних подчеркиваний

#r #regex

#r #регулярное выражение

Вопрос:

может кто-нибудь помочь с этими регулярными выражениями?

 d_total_v_conf.int.low_all
  

Я хочу три выражения: total_v , conf.int.low , all

Я не могу просто захватить элементы до третьей _ , это сложнее, чем это:

 d_share_v_hskill_wc_mean_plus
  

Должно привести share_v_hskill_wc , mean и plus

Первое совпадение для всех символов между вторым и предпоследним _ , второе совпадение занимает все между предпоследним и последним _ , а третье занимает все после последнего _

Ответ №1:

Мы можем использовать sub для захвата групп и создания разделителя, чтобы scan

 f1 <- function(str_input) {
     scan(text = sub("^[^_] _(.*)_([^_] )_([^_] )$",
       "\1,\2,\3", str_input), what = "", sep=",")
 }
f1(str1)
#[1] "total_v"      "conf.int.low" "all" 

f1(str2)
#[1] "share_v_hskill_wc" "mean"              "plus"   
  

Если это data.frame столбец

 library(tidyr)
library(dplyr)
df1 %>%
   extract(col1, into = c('col1', 'col2', 'col3'), 
            "^[^_] _(.*)_([^_] )_([^_] )$")
#               col1         col2 col3
#1           total_v conf.int.low  all
#2 share_v_hskill_wc         mean plus
  

данные

 str1 <- "d_total_v_conf.int.low_all"  
str2 <- "d_share_v_hskill_wc_mean_plus" 
df1 <- data.frame(col1 = c(str1, str2))
  

Комментарии:

1. Спасибо! Работает ли это внутри separate ? Внутри sep аргумента

2. @ArthurCarvalhoBrito это основано на группах захвата, поэтому вы можете использовать extract вместо separate т.е. df1 %>% extract(col1, into = c('col1', 'col2', 'col3'), "^[^_] _(.*)_([^_] )_([^_] )$")

Ответ №2:

Вот одно регулярное выражение, которое выдает три группы в соответствии с запросом:

 (?<=^[^_]_)((?:(?:(?!_).) )|_) (_[^_] $)
  

ДЕМОНСТРАЦИЯ

Идея состоит в том, чтобы использовать поиск, плюс явное совпадение для первой группы, пакет «все, кроме всего» в середине и еще одно явное совпадение для последней части. Возможно, вам потребуется настроить привязки начала и конца, если эти строки отображаются в произвольном тексте.

Ответ №3:

Вы можете использовать {unglue} для этой задачи :

 library(unglue)
x <- c("d_total_v_conf.int.low_all", "d_share_v_hskill_wc_mean_plus")
pattern <- "d_{a}_{b=[^_] }_{c=[^_] }"
unglue_data(x, pattern)
#>                   a            b    c
#> 1           total_v conf.int.low  all
#> 2 share_v_hskill_wc         mean plus
  

в основном вы хотите извлечь a, b и c из шаблона, выглядящего как «d_{a}_{b}_{c}», но где b и c состоят из одного или нескольких символов, не являющихся символами подчеркивания, что и означает «[^_] » в регулярном выражении.