删除 1-3 位数字和字符串之前的所有字符 - r 和正则表达式

Delete all characters before 1-3 digits and string - r and regex

我需要从如下所示的数据中提取毫克数量:

(100) x 10mg zepose valium ..(cipla in strips)
-- 20x2mg -- diclazepam
(10) clonazepam 2mg / roche rivotril 
...

在 R 中,我使用此正则表达式删除 "mg":

之后的所有文本
dataset$quantity <- gsub('mg.+?$','mg',dataset$quantity)

输出是这样的:

(100) x 10mg
-- 20x2mg
(10) clonazepam 2mg

如何删除 'mg' 之前的文字,同时保留数量?范围是从 1mg 到 200mg,所以从个位数到三位数。

有时在 mg 数字之前会有空格,但并非总是如此。然而,一种模式是在 mg 数量之前从来没有数字(除非用空格分隔)。

基于我对正则表达式的有限理解,我正在寻找一个可以删除 1-3 位和 'mg' 之前的所有字符的代码。我环顾四周,找不到我需要的东西。

编辑:

我想要的输出是:

10mg
2mg
2mg

请忽略文本中提到的 1000 毫克(100 x 10 毫克)、40 毫克(20 x 2 毫克)等。我认为我将不得不手工计算这些。

1) sub 匹配 1-3 位数字之前的所有内容,然后是 mg,然后是其他任何内容,并将其替换为包含数字的捕获组(括号内的部分)的匹配项和毫克:

dat <- c("(100) x 10mg zepose valium ..(cipla in strips)", 
"-- 20x2mg -- diclazepam",
"(10) clonazepam 2mg / roche rivotril")

sub(".*?(\d{1,3}mg).*", "\1", dat)
## [1] "10mg" "2mg"  "2mg" 

如果您不想 return mg 部分,则将右括号放在 mg 之前而不是之后。

2) strcapture另一种可能是

strcapture("(\d{1,3}mg)", dat, data.frame(mg = character(0)))

给这个数据框:

    mg
1 10mg
2  2mg
3  2mg

更新:关于计算数量乘以毫克的问题有更新:

DF <- strcapture("(\d+)\D+(\d+)", dat, data.frame(qty = numeric(0), mg = numeric(0)))
transform(DF, total = qty * mg, desc = sub(".*mg *", "", dat))

给予:

  qty mg total                              desc
1 100 10  1000 zepose valium ..(cipla in strips)
2  20  2    40                     -- diclazepam
3  10  2    20                  / roche rivotril

使用 gsub/sub(在这种情况下,哪个无关紧要,因为每行只有一个 mg):

dataset$quantity <- gsub('.+?(\d+\s?mg).+', '\1', dataset$quantity)

str_extract 来自 stringr:

library(stringr)
dataset$quantity = str_extract(dataset$quantity, "\d+\s?mg")

结果:

  quantity
1     10mg
2      2mg
3      2mg

备注:

  1. .+? 延迟匹配任何字符一次或多次。

  2. (\d+\s?mg) 是一个捕获组,它匹配一个数字一次或多次,然后是 space 零次或一次,然后是文字 "mg".

  3. \1 in gsub/sub 将模式替换为第一个捕获组中的任何内容,在本例中为 (\d+\s?mg)。因此 gsub/sub 解决方案有效地删除了除 <digits>[space]mg.

  4. 之外的所有内容
  5. str_extract 是一种不同的方法,它提取模式,而不是替换。在这种情况下,我直接提取\d+\s?mg

数据:

dataset = structure(list(quantity = c("(100) x 10mg zepose valium ..(cipla in strips)", 
"-- 20x2mg -- diclazepam", "(10) clonazepam 2mg / roche rivotril"
)), class = "data.frame", row.names = c(NA, -3L), .Names = "quantity")