我一直在努力使用正则表达式,最近写了一个我认为可以正常工作的表达式,但是我不确定。我向所有花时间在下面检查我的代码的人提出的问题-从理论上讲,它是按照我的意愿进行的吗?
目的:我正在浏览数据集中的每一列,以找出包含以'pharmacy-'开头,后接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))))
答案 0 :(得分:1)
您需要转义特殊字符(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]
的简写。答案 1 :(得分:0)
没有专家,但是您的表情看起来不错,我可能会稍加修改为:
^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*\)$
如果您感兴趣,请在此demo中对表达式进行说明。
确保对R进行必要的转义。
jex.im可视化正则表达式: