使用Regex& amp;分隔R中的列。分开(tidyr)

时间:2018-01-08 18:05:23

标签: r regex tidyr

这是我希望能够做到的 https://regex101.com/r/KchccA/1

我希望匹配中间=和之间的任何字符,同时还要考虑是否存在空捕获组,因为我希望每行填充所有字段。

行示例:在此示例中,Address4,County和Contact名称为null。您还可以看到一些错误/不正确的值。 还需要删除一些初始/结束文本。

ss:sp

然而在R中,当我尝试使用tidyr的单独方法时,我最终得到了不良结果。我没有逃脱它吗?

以下是我的代码:

push/call

结果示例:

sp

最终解决方案

这是我对任何好奇的人的最终解决方案,基于正确的答案格式化以便于查看。

x <- "Please enter an UT location before booking the order.. ADDRESS_VALIDATION_FAILED (SITE_TYPE=uct) (SITE_USE_ID=1000) (CUSTOMER_NAME=cname) (CUSTOMER_NUMBER=2000) (ADDRESS1=addy1) (ADDRESS2=addy2) (ADDRESS3=addy3) (ADDRESS4=) (CITY=.) (STATE=) (ZIP=0000) (COUNTY=) (COUNTRY=NO) (CONTACT_NAME=) The task is raised for line_number: 7"

1 个答案:

答案 0 :(得分:2)

有效输入似乎存在一些不确定性。以下是基于不同假设的几个不同答案。所有都将输入转换为dcf格式(即name:value),然后使用read.dcf

!)平衡括号。

转换为dcf格式(即名称:值)。

我们可以使用gsubfn处理平衡括号。首先创建一个原型对象,其pre函数将计数器k初始化为零,然后对于()的每个匹配,函数fun输入并增加或减少k输出适当的替换字符。有关详细信息,请参阅gsubfn包装插图。

现在从x开始替换开头的垃圾,替换= with:和一个空格然后运行gsubfn匹配(或),然后用我们定义的proto对象运行可选空格。最后使用read.dcf读取转换后的文本。

library(gsubfn)
library(magrittr)

p <- proto(
 pre = function(.) .$k <- 0,
 fun = function(., x) {
  if (x == "(") .$k <- .$k + 1 else if (x == ")") .$k <- .$k - 1
  if (x == "(" && .$k == 1) "" else if (x == ")" && .$k == 0) "\n" else x
})

x %>%
  sub("^.*?\\(", "(", .) %>%
  gsub("=", ": ", .) %>%
  gsubfn("([\\(\\)]) *", p, .) %>%
  textConnection %>%
  read.dcf

2)嵌套括号没有相邻的空格

x <- "(SITE_TYPE=Site1) (SITE_USE_ID=2000) (CUSTOMER_NAME=cname) (CUSTOMER_NUMBER=11111) (ADDRESS1=addy1) (ADDRESS2=addy2) (ADDRESS3=addy3) (ADDRESS4=) (CITY=.) (STATE=) (ZIP=0000) (COUNTY=) (COUNTRY=NO) (CONTACT_NAME=)"


library(magrittr)

x %>%
  paste0(" ") %>%
  sub("^.*?\\(", "", .) %>%
  gsub(" +\\(", " ", .) %>%
  gsub("=", ": ", .) %>%
  gsub("\\) ", "\n", .) %>%
  textConnection %>%
  read.dcf

,并提供:

     SITE_TYPE SITE_USE_ID CUSTOMER_NAME CUSTOMER_NUMBER ADDRESS1 ADDRESS2
[1,] "Site1"   "2000"      "cname"       "11111"         "addy1"  "addy2" 
     ADDRESS3 ADDRESS4 CITY STATE ZIP    COUNTY COUNTRY CONTACT_NAME
[1,] "addy3"  ""       "."  ""    "0000" ""     "NO"    ""     

3)固定关键字遵循左外括号。

对于这一个,内括号可能是不平衡的,但外括号后面总是跟着cn中的一个关键字。

x <- "ADDRESS_VALIDATION_FAILED (SITE_TYPE=site1) (SITE_USE_ID=200) (CUSTOMER_NAME=abc) (CUSTOMER_NUMBER=1000) (ADDRESS1=issue here (some more text) (ADDRESS2=) (ADDRESS3=) (ADDRESS4=) (CITY=city, ) (STATE=na) (ZIP=250) (COUNTY=) (COUNTRY=NA) (CONTACT_NAME=)"

cn <- c("SITE_TYPE", "SITE_USE_ID", "CUSTOMER_NAME", "CUSTOMER_NUMBER", 
"ADDRESS1", "ADDRESS2", "ADDRESS3", "ADDRESS4", "CITY", "STATE", 
"ZIP", "COUNTY", "COUNTRY", "CONTACT_NAME")
rx <- sprintf(".(%s)", paste(cn, collapse = "|"))

x %>%
  sub("^.*?\\(", "(", .) %>%
  gsub("=", ": ", .) %>%
  gsub(rx, "\n\\1", .) %>%
  gsub("\\) *\\n", "\n", .) %>%
  sub("\\)$", "", .) %>%
  textConnection %>%
  read.dcf

,并提供:

     SITE_TYPE SITE_USE_ID CUSTOMER_NAME CUSTOMER_NUMBER
[1,] "site1"   "200"       "abc"         "1000"         
     ADDRESS1                     ADDRESS2 ADDRESS3 ADDRESS4 CITY    STATE
[1,] "issue here (some more text" ""       ""       ""       "city," "na" 
     ZIP   COUNTY COUNTRY CONTACT_NAME
[1,] "250" ""     "NA"    ""          

注意

可重复形式的输入是: