Регулярные выражения для извлечения нестандартной строки - PullRequest
0 голосов
/ 04 июня 2018

Мой вопрос касается использования конструкций lookahead и lookbehind в регулярных выражениях с условными выражениями If-Then-Else в сочетании с str_extract.

В приведенной ниже таблице есть строка UNIT, которую нужно разбитьв его 3 составных части.Формат нестандартный, и я использую regex и str_extract для создания новых столбцов с каждым компонентом.

Я могу легко извлечь начало (3A, 3C и т. Д.) И конец строки (E, A), но средний компонент немного сложнее.Это может быть 1-3 цифры или двухсимвольный код SK, SD или HH.Я могу использовать приведенный ниже код по отдельности, но последняя строка перезаписывает первую.

Итак, мой вопрос, как я могу использовать условные выражения If-Then-Else в регулярных выражениях (? (? =regex) затем | else) в сочетании с str_extract для получения df2 из df1?

df1$C2 = str_extract(df1$UNIT,"(?<=[:upper:])\\d*(?<![:upper:])")

df1$C2 = str_extract(df1$UNIT, "S.$")


df1
ID  UNIT
1   3ASD
2   3C14E
3   3D5E
4   3E15E
5   3ESK
6   3B14A
7   3BHHQ2
8   3E101

df2
ID  UNIT    C1  C2  C3
1   3ASD    3A  SD  NA
2   3C14E   3C  14  E
3   3D5E    3D  5   E
4   3E15E   3E  15  E
5   3ESK    3E  SK  NA
6   3B14A   3B  14  A
7   3BHHQ2  3B  HH  Q2
8   3E101   3E  101 NA

Ответы [ 3 ]

0 голосов
/ 05 июня 2018

Вы можете прочитать в виде таблицы:

 cbind(df1,read.table(text=sub("(..)(\\d+|SK|SD|HH)(.*)","\\1 \\2 \\3",df1$UNIT),fill=T,h=F,col.names = c("C1","C2","C3"),na.strings = ""))
  ID   UNIT C1  C2   C3
1  1   3ASD 3A  SD <NA>
2  2  3C14E 3C  14    E
3  3   3D5E 3D   5    E
4  4  3E15E 3E  15    E
5  5   3ESK 3E  SK <NA>
6  6  3B14A 3B  14    A
7  7 3BHHQ2 3B  HH   Q2
8  8  3E101 3E 101 <NA>
0 голосов
/ 05 июня 2018
Problem solved using the following code:

        df2$C1=  str_extract(df1$Unit, "^[:digit:][:upper:]")
    #if the start of the string is a digit and upper case letter then extract it into col C1

        df2$C2= str_extract(df1$Unit,"(?<=[:upper:])\\d*(?<![:upper:])|(?<=[:upper:])[[:upper:]][[:upper:]](?<=[:upper:])")
    #if a digit follows an uppercase letter or is behind another uppercase letter then extract all digits in between and extract it into C2
    #OR if two uppercase letters follow an uppercase letter or come before another uppercase letter then extract all letters in between and extract it into C2

        df2$C3=  str_extract(df1$Unit, "(?<=[:digit:])[A-E]$|Q.$")
    #if a the last a letter is A-E and is preceded by a digit then extract the letter into C3
    #OR if the last character is preceded by the letter Q then extract Q and the character
0 голосов
/ 05 июня 2018

Я думаю, что вы можете "кодировать" условия в одном регулярном выражении, оборачивая отдельные значения группами захвата, а затем использовать str_match, чтобы фактически получить доступ к этим захватам, чтобы позже использовать их для создания столбцов:

library(stringr)
df <- data.frame(ID=c(1,2,3,4,5,6,7,8), UNIT=c("3ASD","3C14E","3D5E","3E15E","3ESK","3B14A","3BHHQ2","3E101"))
rx = "^([0-9][[:upper:]])([0-9]{1,3}|S[KD]|HH)([[:upper:]][0-9]*)?$"
match_table <- str_match(df$UNIT, rx)
df$C1 <- match_table[,2]
df$C2 <- match_table[,3]
df$C3 <- match_table[,4]
> df
  ID   UNIT C1  C2   C3
1  1   3ASD 3A  SD <NA>
2  2  3C14E 3C  14    E
3  3   3D5E 3D   5    E
4  4  3E15E 3E  15    E
5  5   3ESK 3E  SK <NA>
6  6  3B14A 3B  14    A
7  7 3BHHQ2 3B  HH   Q2
8  8  3E101 3E 101 <NA>

См. Демонстрационную версию regex .

Подробности

  • ^ - начало строки
  • ([0-9][[:upper:]]) - группа C1: цифра, а затем заглавная буква
  • ([0-9]{1,3}|S[KD]|HH) - группа C2: 1, 2 или 3 цифры или SK, SD или HH
  • ([[:upper:]][0-9]*)? - необязательная группа C3: заглавная буква, за которой следуют 0+ цифр
  • $ - конец строки,
...