使用正则表达式提取混合分数和文本,也可能包含混合分数与R (stringr)



请参阅下面我正在使用的数据示例,但是,我总共有100K多个条目。

注意注释中的...UNIT下是为了使它适合。例如,完整的UNIT文本为第一项为4- to 5-mm-diameter,第五项为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"

我的目标是提取QTYUNIT,如代码注释中所示,从第一个到最后一个条目为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.

您可以使用

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]):一个或多个数字后面可选出现一个或多个空格,一个或多个数字,/和一个或多个数字,或/包含一个或多个数字
  • s+-一个或多个空白
  • ((?:d+(?:-?in(?:ch)?|")?s+)*S+(?:s+tos+(?:d+(?:-?in(?:ch)?|")?s+)*S+)?)-第2组(m[,3]):
    • (?:d+(?:-?in(?:ch)?|")?s+)*- 0个或多个数字出现,后跟可选的"-,in,然后是可选的ch子字符串,然后是一个或多个空白
    • S+-一个或多个空格以外的字符("word")
    • (?:s+tos+(?:d+(?:-?in(?:ch)?|")?s+)*S+)?-可选的出现:
      • s+tos+-to包含一个或多个空白
      • (?:d+(?:-?in(?:ch)?|")?s+)*-见上文
      • S+-一个或多个空格以外的字符。

最新更新