#r #regex #stringr
#r #регулярное выражение #stringr
Вопрос:
Пожалуйста, смотрите Ниже пример данных, с которыми я работаю, однако у меня в общей сложности более 100 тысяч записей.
обратите внимание, что ...
в комментарии ниже UNIT
это просто для того, чтобы оно соответствовало. Например, полный UNIT
текст для первого элемента is 4- to 5-mm-diameter
и пятого элемента is 3 1/2- to 4-inch-diameter
и т.д.
library(tidyverse)
#i QTY UNIT
parts <- c("6 4- to 5-mm-diameter plugs", #1 6 4- to...diameter
"6 large bricks", #2 6 large
"1 1/3 shipment concrete", #3 1.33 shipment
"1 (14- to 15-oz) gold bars", #4 1 (14- to 15-oz)
"16 3 1/2- to 4-inch-diameter caps", #5 16 3 1/2- to...eter
"1 1/2 tons sand", #6 1.5 tons
"2 1 1/4- to 3-inch diameter caps", #7 2 1 1/4- to...eter
"1/3 shipment cement") #8 .333 shipment
Я добился некоторого умеренного успеха, работая с некоторыми ответами на SO, но я сталкиваюсь с проблемами, когда UNIT
текст также содержит смешанные дроби, как в пунктах 1 и 5:
# Goal: extract QTY as mixed frac
parts %>%
str_extract("(\d [\/\d[ ]?]*|\d*)")
# i=1, 5 broken
#[1] "6 4" "6 " "1 1/3 " "1 " "16 3 1/2" "1 1/2 "
# Goal: extract UNIT word
parts %>%
str_extract("[[:graph:]]{3,11}|[- to ].{5,21}")
# all i with some problem
# [1] " 4- to 5-mm-diameter p" " large bricks" " 1/3 shipment concrete"
# [4] " (14- to 15-oz) gold b" " 3 1/2- to 4-inch-diam" " 1/2 tons sand"
Мои цели — извлечь QTY
и UNIT
, как показано в комментарии к коду, от первой до последней записи, как 6, 6, 1 1/3, 1, 16, 1, 2, 1/3
— кроме того, я пытаюсь извлечь текст в разделе UNIT
сокращенный, чтобы он поместился в разделе код — вот он полностью : 4- to 5-mm-diameter, large, shipment, (14- to 15-oz), 3 1/2- to 4-inch-diameter, tons, 1 1/4- to 3-inch diameter, shipment
.
Моя интуиция подсказывает, что я должен сделать это в два этапа, но, пожалуйста, дайте мне знать, если есть лучшие способы добиться этого.
Спасибо.
редактировать: добавлен критический пример номер 8.
Комментарии:
1. Я предположил, что ответ на любой изолированный вопрос может не решить его, т.Е. Решения для
QTY
не учитывают решения для строк, подобныхUNIT
в моем примере.2. Проверьте ideone.com/pqbBC5 , работает ли это для вас?
3. Я добавил в список дополнительный элемент # 8, которого у меня раньше не было.
4. Планируются ли еще какие-либо дополнения?
Ответ №1:
Вы можете использовать
m <- str_match(parts, '^(\d (?:\s \d /\d )?|\d /\d )\s ((?:\d (?:-?in(?:ch)?|")?\s )*\S (?:\s to\s (?:\d (?:-?in(?:ch)?|")?\s )*\S )?)')
qty <- m[,2]
# => [1] "6" "6" "1 1/3" "1" "16" "1 1/2" "2" "1/3"
unit <- m[,3]
# => [1] "4- to 5-mm-diameter" "large"
# [3] "shipment" "(14- to 15-oz)"
# [5] "3 1/2- to 4-inch-diameter" "tons"
# [7] "1 1/4- to 3-inch diameter" "shipment"
Смотрите демонстрацию R и демонстрацию регулярных выражений. Подробные сведения:
^
— начало строки(d (?:s d /d )?|d /d )
— Группа 1 (m[,2]
): одна или несколько цифр, за которыми следует необязательное вхождение одного или нескольких пробелов, одной или нескольких цифр/
и одной или нескольких цифр, или a/
, заключенный в одну или несколько цифр.s
— один или несколько пробелов((?:d (?:-?in(?:ch)?|")?s )*S (?:s tos (?:d (?:-?in(?:ch)?|")?s )*S )?)
— Группа 2 (m[,3]
):(?:d (?:-?in(?:ch)?|")?s )*
— ноль или более вхождений одной или нескольких цифр , за которыми следует необязательное вхождение a"
или необязательный-
,in
а затем необязательнаяch
подстрока , а затем один или несколько пробеловS
— один или несколько символов, отличных от пробела («слово»)(?:s tos (?:d (?:-?in(?:ch)?|")?s )*S )?
— необязательное возникновение:s tos
—to
заключено одним или несколькими пробелами(?:d (?:-?in(?:ch)?|")?s )*
— см . вышеS
— один или несколько символов, отличных от пробелов.
Комментарии:
1. Спасибо за этот выдающийся ответ.