Break string into several columns using tidyr::extract regex
In the regex used, we are matchng one more more punctuation characters ([[:punct:]]+
) i.e. @
followed by capturing the numeric part ((\\d+)
- this will be our first column of interest), followed by one or more white-space (\\s+
), followed by the second capture group (\\S+
- one or more non white-space character i.e. "ANO_CENSO" for the first row), followed by space (\\s+
), then we capture the third group (([[:alum:]$]+)
- i.e. one or more characters that include the alpha numeric along with $
so as to match $Char1
), next we match one or more characters that are not a letter ([^A-Za-z]+
- this should get rid of the space and *
) and the last part we capture one or more characters that are not *
(([^*]+)
.
sasdic %>%
extract(a, into=c('int_pos', 'var_name', 'x', 'label'),
"[[:punct:]](\\d+)\\s+(\\S+)\\s+([[:alnum:]$]+)[^A-Za-z]+([^*]+)")
# int_pos var_name x label
#1 1 ANO_CENSO 5 Ano do Censo
#2 71 TP_SEXO $Char1 Sexo
#3 72 TP_COR_RACA $Char1 Cor/raça
#4 74 FK_COD_PAIS_ORIGEM 4 Código País de origem
This is another option, though it uses the data.table package instead of tidyr:
library(data.table)
setDT(sasdic)
# split label
sasdic[, c("V1","label") := tstrsplit(a, "/\\*|\\*/")]
# remove leading "@", split remaining parts
sasdic[, c("int_pos","var_name","x") := tstrsplit(gsub("^@","",V1)," +")]
# remove unneeded columns
sasdic[, c("a","V1") := NULL]
sasdic
# label int_pos var_name x
# 1: Ano do Censo 1 ANO_CENSO 5.
# 2: Sexo 71 TP_SEXO $Char1.
# 3: Cor/raça 72 TP_COR_RACA $Char1.
# 4: Código País de origem 74 FK_COD_PAIS_ORIGEM 4.
This assumes that the "remaining parts" (aside from the label) are space-separated.
This could also be done in one block (which is what I would do):
sasdic[, c("a","label","int_pos","var_name","x") := {
x = tstrsplit(a, "/\\*|\\*/")
x1s = tstrsplit(gsub("^@","",x[[1]])," +")
c(list(NULL), x1s, x[2])
}]