在可以出现零次或多次的字符之后截断R中字符串的结尾

Ton*_* M. 8 string truncate r

我有以下数据:

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")
Run Code Online (Sandbox Code Playgroud)

我想创建一个新的向量,在存在":"的情况下仅保留第一个":"之前的文本,而当":"不存在时保留整个单词.

我试过用:

temp=data.frame(matrix(unlist(str_split(temp,pattern=":",n=2)), 
+                        ncol=2, byrow=TRUE))
Run Code Online (Sandbox Code Playgroud)

但是在没有":"的情况下它不起作用

我知道这个问题非常类似于: 截断R中某个字符的字符串,它使用了:

sub("^[^.]*", "", x)
Run Code Online (Sandbox Code Playgroud)

但是我对正则表达式并不是很熟悉,并且一直在努力扭转这个例子,只保留字符串的开头.

And*_*rie 15

你可以用一个简单的正则表达式解决这个问题:

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"     
Run Code Online (Sandbox Code Playgroud)

正则表达式如何工作:

  • "(.*?):.*"寻找重复的任何字符集,.*但修改它?不要贪心.接下来应该是冒号然后是任何字符(重复)
  • 用括号内的位替换整个字符串 - "\\1"

需要理解的是,默认情况下,任何正则表达式匹配都是贪婪的.通过将其修改为非贪婪,第一个模式匹配不能包括冒号,因为括号后面的第一个字符是冒号.冒号后的正则表达式恢复默认值,即贪心.


Gre*_*now 9

另一种方法是寻找第一个":"并将其替换为任何东西:

yy <- sub(":.*$", "", yy )
Run Code Online (Sandbox Code Playgroud)

如果没有找到":",则不会替换任何内容,而是获得整个原始字符串.如果有一个":",则第一个与之后的所有内容相匹配,然后将其替换为"("),删除它并将所有内容保留到第一个冒号.