Правильно ли совпадают мои регулярные выражения R? - PullRequest
1 голос
/ 26 июня 2019

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

Цель: я просматриваю каждый столбец в моем наборе данных, чтобы определить строки, содержащие строкикоторые начинаются с «аптека -», за которыми следует любой из 13 типов лекарств, и заканчиваются скобками с числом внутри.Вот несколько примеров:

pharmacy - oxycodone/acetaminophen (3)

pharmacy - fentanyl (2.83)

pharmacy - hydromorphone (6.8)

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

viz$med_2 <- apply(viz, 1, function(x)as.integer(any(grep("^pharmacy+[ -]+(codeine|oxycodone|fentanyl|hydrocodone|hydromophone|mathadone|morphine sulfate|oxycodone|oxycontin|roxicodone|tramadol|hydrocodone/acetaminophen|oxycodone/acetaminophen)+[ -]+[(]+[0-9]+", x))))

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Вам нужно экранировать специальные символы (с двойной обратной косой чертой \\ в R), иначе регулярное выражение выдаст ошибку.

В регулярном выражении + означает совпадение символа один или несколько раз. Таким образом, pharmacy+ соответствует pharmac, за которым следует одно или бесконечное число y, что, вероятно, не нужно.

Я бы рекомендовал использовать \\s вместо простого пробела. \\s соответствует любому символу пробела [ \t\r\n\f] и поэтому более универсален.

Вот как бы я это сделал.

viz <- data.frame(
  med_2 = c(
    "pharmacy - oxycodone/acetaminophen (3)",
    "pharmacy - fentanyl (2.83)",
    "pharmacy - hydromorphone (6.8)"
  )
)

# list of the different drug names
drugs_ls <- c(
  "codeine",
  "oxycodone",
  "fentanyl",
  "hydrocodone",
  "hydromophone",
  "mathadone",
  "morphine sulfate",
  "oxycontin",
  "roxicodone",
  "tramadol",
  "acetaminophen"
)

# concatenate and separate drug names with a pipe
drugs_re <- paste0(drugs_ls, collapse = "|")

# generate the regex
med_re <- paste0("^(?i)pharmacy[\\s-]+(?:", drugs_re, ")(?:\\/acetaminophen)?[\\s-]+\\(\\d")

viz$med_2 <- apply(viz, 1, function(x)as.integer(any(grep(med_re, x, perl = TRUE))))

viz
#  med_2
#1     1
#2     1
#3     0

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

^(?i)pharmacy[\\s-]+(?:codeine|oxycodone|fentanyl|hydrocodone|hydromophone|mathadone|morphine sulfate|oxycontin|roxicodone|tramadol|acetaminophen)(?:\\/acetaminophen)?[\\s-]+\\(\\d
  • (?i) делает регистр нечувствительным к регистру.
  • (?:) создает группу без захвата.
  • ? соответствует персонажу / группе или ничему.
  • \\d является сокращением для [0-9].
0 голосов
/ 26 июня 2019

Никакого эксперта, но ваше выражение выглядит великолепно, я бы, возможно, немного изменил бы его на:

^pharmacy\s*-\s*(codeine|oxycodone|fentanyl|hydrocodone|hydromophone|mathadone|morphine sulfate|oxycodone|oxycontin|roxicodone|tramadol|hydrocodone\/acetaminophen|oxycodone\/acetaminophen)\s*\(\s*[0-9]+(\.[0-9]+)?\s*\)$

В этой демоверсии приведено объяснение выражения, если вам может быть интересно.

Удостоверьтесь в необходимости побега для R.

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

...