String 在一个可以出现零次或多次的字符后截断R中字符串的结尾
我有以下数据:String 在一个可以出现零次或多次的字符后截断R中字符串的结尾,string,r,truncate,String,R,Truncate,我有以下数据: temp<-c("AIR BAGS:FRONTAL" ,"SERVICE BRAKES HYDRAULIC:ANTILOCK", "PARKING BRAKE:CONVENTIONAL", "SEATS:FRONT ASSEMBLY:POWER ADJUST", "POWER TRAIN:AUTOMATIC TRANSMISSION", "SUSPENSION", "ENGINE AND ENGINE COOLING:ENGINE",
temp<-c("AIR BAGS:FRONTAL" ,"SERVICE BRAKES HYDRAULIC:ANTILOCK",
"PARKING BRAKE:CONVENTIONAL",
"SEATS:FRONT ASSEMBLY:POWER ADJUST",
"POWER TRAIN:AUTOMATIC TRANSMISSION",
"SUSPENSION",
"ENGINE AND ENGINE COOLING:ENGINE",
"SERVICE BRAKES HYDRAULIC:ANTILOCK",
"SUSPENSION:FRONT",
"ENGINE AND ENGINE COOLING:ENGINE",
"VISIBILITY:WINDSHIELD WIPER/WASHER:LINKAGES")
但在没有以下情况下不起作用:
我知道这个问题非常类似于:
,其中使用:
sub("^[^.]*", "", x)
但我对正则表达式不太熟悉,因此很难将该示例颠倒过来,只保留字符串的开头。可以做到这一点(假设数据位于字符向量中):
x sapply(str_split(x,“:”,[”,1)
[1] “foobar”“foo”“foo1”“foobar”
在这种情况下
yy<-c("AIR BAGS:FRONTAL",
"SERVICE BRAKES HYDRAULIC:ANTILOCK",
"PARKING BRAKE:CONVENTIONAL",
"SEATS:FRONT ASSEMBLY:POWER ADJUST",
"POWER TRAIN:AUTOMATIC TRANSMISSION",
"SUSPENSION",
"ENGINE AND ENGINE COOLING:ENGINE",
"SERVICE BRAKES HYDRAULIC:ANTILOCK",
"SUSPENSION:FRONT",
"ENGINE AND ENGINE COOLING:ENGINE",
"VISIBILITY:WINDSHIELD WIPER/WASHER:LINKAGES")
yy<-gsub("([^:]*).*","\\1",yy)
yy
yy您可以用一个简单的正则表达式来解决这个问题:
sub("(.*?):.*", "\\1", x)
[1] "AIR BAGS" "SERVICE BRAKES HYDRAULIC" "PARKING BRAKE" "SEATS"
[5] "POWER TRAIN" "SUSPENSION" "ENGINE AND ENGINE COOLING" "SERVICE BRAKES HYDRAULIC"
[9] "SUSPENSION" "ENGINE AND ENGINE COOLING" "VISIBILITY"
正则表达式的工作原理:
“(.*):.*”
查找任何字符的重复集*
,但使用?
将其修改为不贪婪。这应该后跟冒号,然后是任何字符(重复)
- 用括号内的位替换整个字符串-
“\\1”
需要理解的是,任何正则表达式匹配在默认情况下都是贪婪的。通过将其修改为非贪婪,第一个模式匹配不能包含冒号,因为括号后的第一个字符是冒号。冒号后的正则表达式返回默认值,即贪婪。另一种方法是查找第一个“:”并将其及其后的任何内容替换为零:
yy <- sub(":.*$", "", yy )
yy很抱歉将此作为回答。作为对所用时间的回应:
> yy<-rep("foo1:bar1",times=100000)
> system.time(yy1<-sapply(strsplit(yy,":"),'[',1))
user system elapsed
0.26 0.00 0.27
>
> system.time(yy2<-sub("(.*?):.*", "\\1", yy))
user system elapsed
0.1 0.0 0.1
>
> system.time(yy3 <- sub(":.*$", "", yy ))
user system elapsed
0.08 0.00 0.07
>
> system.time(yy4<-gsub("([^:]*).*","\\1",yy))
user system elapsed
0.09 0.00 0.09
yy系统时间(yy1
>系统时间(yy2)
>系统时间(yy3)
>system.time(yy4谢谢!对正则表达式(+1)的解释这是我马上想到的答案。就速度而言,你认为这与正则表达式的解决方案相比如何?@Dason这也是我的想法,因为我不是真的“思考”在正则表达式中还没有,但我对速度没有太高的期望。有用的扩展评论。我发现令人振奋的是,在我的大脑看来最简单的正则表达式,@GregSnow的正则表达式也是最快的。另外两个正则表达式解决方案提供了信息,说明了字符类是启动“否定”的一种方式以及使用未修改的“?”来抑制贪婪行为的解释。
yy <- sub(":.*$", "", yy )
> yy<-rep("foo1:bar1",times=100000)
> system.time(yy1<-sapply(strsplit(yy,":"),'[',1))
user system elapsed
0.26 0.00 0.27
>
> system.time(yy2<-sub("(.*?):.*", "\\1", yy))
user system elapsed
0.1 0.0 0.1
>
> system.time(yy3 <- sub(":.*$", "", yy ))
user system elapsed
0.08 0.00 0.07
>
> system.time(yy4<-gsub("([^:]*).*","\\1",yy))
user system elapsed
0.09 0.00 0.09