Что не так в моем регулярном выражении для извлечения частей строки в R?

#r #regex #extract

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

Вопрос:

Во фрейме данных есть строка, подобная этой:

 df <- data.frame (Product = c("Chocolate Some_brand 200g 180ml PKG",
                              "Strawberry Grown_locally 380g"))
  

Я пытаюсь извлечь только значение миллилитров в другую переменную, используя эти два разных способа:

 df %>% mutate(
   volume = str_extract(Product, '\d ml|\d  ml')
)
# the return is:
# 180ml
# NA
  

Пытаясь вернуть sabe, но без строки ml, я пытаюсь что-то вроде этого:

 df %>% mutate(
   volume = str_extract(NombreProducto, '\d [^ml]|\d [^ ml]')
)
# the return is:
# 180
# 380g
  

Что я должен сделать, чтобы получить эти результаты?

 # 180
# NA
  

Ответ №1:

Вы можете использовать (?=s*ml) предварительный просмотр:

 str_extract(df$Product, '\d (?=\s*ml)')
## => [1] "180" NA 
  

Обратите внимание, что вы можете убедиться, что ml соответствует целому слову, добавив b границу слова после него, и вы можете поддерживать значения с плавающей точкой, заменив d на d*.?d (или d (?:[,.]d )? ):

 str_extract(df$Product, '\d*\.?\d (?=\s*ml\b)')
  

Подробности шаблона

  • d — 1 или более цифр
  • (?=s*ml) — положительный предварительный просмотр, который требует 0 или более пробелов, а затем ml сразу справа от текущего местоположения, но не добавляет соответствующий текст к общему значению соответствия, поскольку шаблоны предварительного просмотра не потребляют.

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

1. Спасибо Виктору! Это работает просто отлично!!! Я много работаю с регулярными выражениями, и ваше объяснение было действительно ясным.

2. @DiegodeLima Если у вас все еще возникают проблемы с этим, просто оставьте комментарий. Я добавил еще несколько опций на случай, если ваши данные неоднородны, например, d (?:[,.]d )? для сопоставления чисел с плавающей точкой с запятыми или точками в качестве десятичных разделителей.

3. Виктор, все в порядке. Я заметил ваши обновления, и опции также будут полезны в моем коде.