我的问题与使用if-Then-Else Conditionals结合str_extract的正则表达式中的前瞻和后瞻构造有关。
我在下表中有一个名为UNIT的字符串,需要将其分解为3个组成部分。格式是非标准的,我使用regex和str_extract为每个组件创建新列。
我可以很容易地提取开始(3A,3C等)和字符串(E,A)的结尾,但中间组件有点困难。它可以是1-3位数,或SK,SD或HH的两个字符代码。我可以单独使用下面的代码,但后一行会覆盖前者。
所以,我的问题是,如何使用正则表达式中的If-Then-Else条件(?(?= regex)然后| else)与str_extract结合使用来从df1获取df2?
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
答案 0 :(得分:2)
我认为你可以在一个正则表达式中“编码”条件,用捕获组包装单独的值,然后使用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 demo。
<强>详情
^
- 字符串开头([0-9][[:upper:]])
- 组C1
:数字,然后是大写字母([0-9]{1,3}|S[KD]|HH)
- 小组C2
:1,2或3位数,或SK
,SD
或HH
([[:upper:]][0-9]*)?
- 可选组C3
:大写字母后跟0+位数$
- 字符串结束,答案 1 :(得分:1)
您可以以表格形式阅读:
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>
答案 2 :(得分:0)
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