сформулируйте группы захвата для непоследовательно представленных подстрок

#r #regex #tidyr

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

Вопрос:

У меня есть записи интервью, которые частично составлены нерегулярно:

 tst lt;- c("In: ja COOL; #00:04:24-6# ",   " in den vier, FÜNF wochen, #00:04:57-8# ",  "In: jah, #00:02:07-8# ",  "In: [ja; ] #00:03:25-5# [ja; ] #00:03:26-1#",  " also jA:h; #00:03:16-6# (1.1)",  "Bz: [E::hm; ] #00:03:51-4# (3.0) ",  "Bz: [mhmh, ]",  " in den bilLIE da war;")  

Что мне нужно сделать, так это структурировать эти данные, извлекая их ключевые элементы в столбцы фрейма данных. Существует четыре таких ключевых элемента:

  • Role в интервью: интервьюируемый или интервьюер
  • Utterance : речь партнеров по интервью
  • Timestamp указано # с обоих концов
  • Gap обозначается десятичным числом в скобках

Проблема в том, что и Timestamp то, и Gap другое предоставляется непоследовательно. Хотя я могу сделать последнюю группу захвата Gap необязательной, те строки, которые ни имеют Timestamp , ни Gap не отображаются правильно:

Я использую extract из tidyr для извлечения:

 library(tidyr) data.frame(tst) %gt;%  extract(col = tst,  into = c("Role", "Utterance", "Timestamp", "Gap"),  regex = "^(\w{2}:\s|\s )([\S\s] ?)\s*#([^#] )?#\s*(\([0-9.] \))?\s*")  Role Utterance Timestamp Gap 1 In: ja COOL; 00:04:24-6  2 in den vier, FÜNF wochen, 00:04:57-8  3 In: jah, 00:02:07-8  4 In: [ja; ] 00:03:25-5  5 also jA:h; 00:03:16-6 (1.1) 6 Bz: [E::hm; ] 00:03:51-4 (3.0) 7 lt;NAgt; lt;NAgt; lt;NAgt; lt;NAgt; 8 lt;NAgt; lt;NAgt; lt;NAgt; lt;NAgt;  

Как можно уточнить регулярное выражение, чтобы я получил желаемый результат:

 Role Utterance Timestamp Gap 1 In: ja COOL; 00:04:24-6  2 in den vier, FÜNF wochen, 00:04:57-8  3 In: jah, 00:02:07-8  4 In: [ja; ] 00:03:25-5  5 also jA:h; 00:03:16-6 (1.1) 6 Bz: [E::hm; ] 00:03:51-4 (3.0) 7 Bz: [mhmh, ] 8 in den bilLIE da war;  

Ответ №1:

Альтернативой сложному регулярному выражению является использование нескольких извлечений с более простыми регулярными выражениями. Затем преобразуйте любые NA в «» и удалите ненужные пробелы.

 library(dplyr) library(tidyr)  data.frame(tst) %gt;%  extract(tst, "Gap", "(\(.*?\))", remove = FALSE) %gt;%  extract(tst, "Timestamp", "(#.*?#)", remove = FALSE) %gt;%  extract(tst, c("Role", "Utterance"), "^(\S :|)([^#]*)") %gt;%  mutate(across(, coalesce, ""), Utterance = trimws(Utterance))  

дающий:

 Role Utterance Timestamp Gap 1 In: ja COOL; #00:04:24-6#  2 in den vier, FÜNF wochen, #00:04:57-8#  3 In: jah, #00:02:07-8#  4 In: [ja; ] #00:03:25-5#  5 also jA:h; #00:03:16-6# (1.1) 6 Bz: [E::hm; ] #00:03:51-4# (3.0) 7 Bz: [mhmh, ]  8 in den bilLIE da war;   

Ответ №2:

Вы можете обновить свой шаблон, чтобы использовать свои 4 группы захвата, и сделать последнюю часть необязательной, при необходимости сопоставив 3-ю группу, а затем 4-ю группу и утвердив конец строки:

 library(tidyr)  tst lt;- c("In: ja COOL; #00:04:24-6# ",   " in den vier, FÜNF wochen, #00:04:57-8# ",  "In: jah, #00:02:07-8# ",  "In: [ja; ] #00:03:25-5# [ja; ] #00:03:26-1#",  " also jA:h; #00:03:16-6# (1.1)",  "Bz: [E::hm; ] #00:03:51-4# (3.0) ",  "Bz: [mhmh, ]",  " in den bilLIE da war;")   data.frame(tst) %gt;%  extract(col = tst,  into = c("Role", "Utterance", "Timestamp", "Gap"),  regex = "^(\w{2}:\s|\s )([\s\S]*?)(?:\s*#([^#] )(?:#\s*(\([0-9.] \))?\s*)?)?$")  

Выход

 Role Utterance Timestamp Gap 1 In: ja COOL; 00:04:24-6  2 in den vier, FÜNF wochen, 00:04:57-8  3 In: jah, 00:02:07-8  4 In: [ja; ] #00:03:25-5# [ja; ] 00:03:26-1  5 also jA:h; 00:03:16-6 (1.1) 6 Bz: [E::hm; ] 00:03:51-4 (3.0) 7 Bz: [mhmh, ]  8 in den bilLIE da war;