Regex для извлечения числа и его единицы измерения, которые отделены строкой от интересующего слова - PullRequest
0 голосов
/ 05 сентября 2018

Я изучаю R и пытаюсь использовать регулярные выражения для извлечения конкретного текста. Я хотел бы получить число и единицу измерения из рецепта конкретного ингредиента.

Например, для следующего текста:

text <-  c("0.5 Tb of butter","3 grams (0.75 sticks) of chilled butter","2 tbs softened butter", "0.3 Tb of milk")

Я хотел бы извлечь числа и единицы, относящиеся только к маслу, то есть:

0.5 Tb
3 grams
2 tbs

Я думаю, что это лучше всего сделать с помощью регулярных выражений, но я довольно новичок в этом, поэтому я немного борюсь.

Используя str_match, я могу получить число перед определенной единицей, как это:

str_match(text, "\\s*(\\d+)\\s*Tb")
     [,1]   [,2]
[1,] "5 Tb" "5" 
[2,] NA     NA  
[3,] NA     NA  
[4,] "3 Tb" "3" 

Но как я могу получить только те значения, которые относятся к маслу и для диапазона единиц. Можно ли составить список возможных единиц (то есть грамм, тбс, тб и т. Д.) И попросить их сопоставить с любым из них (чтобы в этом примере граммы соответствовали, но не соответствовали палкам)?

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

Спасибо за помощь.

Ответы [ 4 ]

0 голосов
/ 05 сентября 2018

Основным решением R было бы grep выделить строки масла, а затем использовать read.table для их анализа, учитывая, что совпадающие элементы всегда являются первыми двумя полями. Пакеты не используются, и единственное используемое регулярное выражение - это простое выражение butter.

butter <- grep("butter", text, value = TRUE)
read.table(text = butter, fill = TRUE, as.is = TRUE)[1:2]

дает:

   V1    V2
1 0.5    Tb
2 3.0 grams
3 2.0   tbs
0 голосов
/ 05 сентября 2018

Возможно, вы захотите взглянуть на что-то вроде этого ([\d.]+)\s([a-zA-Z]+).*butter

0 голосов
/ 05 сентября 2018
sub("^(\\S+\\s+\\S+).*", "\\1", text[grepl("butter", text)])
[1] "0.5 Tb"  "3 grams" "2 tbs"

\\s+ для сопоставления с любым количеством пробелов и \\S+ для сопоставления с любым количеством пробелов. ^ чтобы начать с начала.

text[grepl("butter", text)] возвращает только те текстовые элементы, которые содержат слово butter. Perhaphs добавляет аргумент ignore.case = TRUE к grepl(), чтобы он также совпадал с Butter ...

0 голосов
/ 05 сентября 2018

Можно было бы обнаружить «сливочное масло» в строках, а затем использовать str_extract

str_extract(grep("butter", text, value = TRUE), "[0-9.]+\\s+\\w+")
#[1] "0.5 Tb"  "3 grams" "2 tbs"

Или используя str_detect с str_extract

library(tidyverse)
str_detect(text, "butter") %>% 
    extract(text, .) %>%
    str_extract("[0-9.]+\\s+\\w+")
#[1] "0.5 Tb"  "3 grams" "2 tbs"    
...