如何仅在第一个数字上拆分字符串

时间:2017-02-09 10:18:14

标签: r regex strsplit

所以我有一个街道地址的数据集,它们的格式非常不同。例如:

d <- c("street1234", "Street 423", "Long Street 12-14", "Road 18A", "Road 12 - 15", "Road 1/2")

从此我想创建两列。 1. X:街道地址和 Y:随着数字+随后的一切。像这样:

X           Y
Street      1234
Street      423
Long Street 12-14
Road        18A
Road        12 - 15
Road        1/2

到目前为止,我已尝试过strsplit,并在此处遵循了一些类似的问题,例如:strsplit(d, split = "(?<=[a-zA-Z])(?=[0-9])", perl = T))。我似乎无法找到正确的正则表达式。

非常感谢任何帮助。提前谢谢!

4 个答案:

答案 0 :(得分:7)

字母和数字之间可能有空格,因此在外观之间添加\s*(零个或多个空白符号):

> strsplit(d, split = "(?<=[a-zA-Z])\\s*(?=[0-9])", perl = TRUE)
[[1]]
[1] "street" "1234"  

[[2]]
[1] "Street" "423"   

[[3]]
[1] "Long Street" "12-14"      

[[4]]
[1] "Road" "18A" 

[[5]]
[1] "Road"    "12 - 15"

[[6]]
[1] "Road" "1/2" 

如果您想基于此创建列,您可以利用 tidyr 包中的separate

> library(tidyr)
> separate(data.frame(A = d), col = "A" , into = c("X", "Y"), sep = "(?<=[a-zA-Z])\\s*(?=[0-9])")
            X       Y
1      street    1234
2      Street     423
3 Long Street   12-14
4        Road     18A
5        Road 12 - 15
6        Road     1/2

答案 1 :(得分:3)

使用stringrlibrary(stringr) ind <- str_locate(d, '[0-9]+')[,1] setNames(data.frame(do.call(rbind, Map(function(x, y) trimws(substring(x, seq(1, nchar(x), y-1), seq(y-1, nchar(x), nchar(x)-y+1))), d, ind)))[,1:2]), c('X', 'Y')) # X Y #1 street 1234 #2 Street 423 #3 Long Street 12-14 #4 Road 18A #5 Road 12 - 15 #6 Road 1/2 来查找字符串中第一个数字然后根据该位置进行拆分的非正则表达式方法,即

"Road 12 - 15"

注意您收到(无害)警告,该警告是[1] "Road" "12 - 15" ""字符串拆分的结果,该字符串为style.css

答案 2 :(得分:3)

这也有效:

do.call(rbind,strsplit(sub('([[:alpha:]]+)\\s*([[:digit:]]+)', '\\1$\\2', d), split='\\$'))
#     [,1]          [,2]     
#[1,] "street"      "1234"   
#[2,] "Street"      "423"    
#[3,] "Long Street" "12-14"  
#[4,] "Road"        "18A"    
#[5,] "Road"        "12 - 15"
#[6,] "Road"        "1/2"    

答案 3 :(得分:2)

我们可以将read.csvsub

中的base R一起使用
read.csv(text=sub("^([A-Za-z ]+)\\s*([0-9]+.*)", "\\1,\\2", d), 
        header=FALSE, col.names = c("X", "Y"), stringsAsFactors=FALSE)
#             X       Y
#1       street    1234
#2      Street      423
#3 Long Street    12-14
#4        Road      18A
#5        Road  12 - 15
#6        Road      1/2