正则表达式 - 使用字符定义边界&分隔符

时间:2016-12-29 16:44:20

标签: r regex

我意识到这是一个相当简单的问题,我在整个网站上进行了搜索,但似乎无法让我的语法适合以下正则表达式的挑战。我想做两件事。首先让正则表达式获取前三个字符并以分号停止。例如,我的字符串可能如下所示:

Apt;House;Condo;Apts;

我想去这里

Apartment;House;Condo;Apartment

我还想创建一个正则表达式来替换分隔符之间的单词,同时保持其他单词不变。例如,我想离开这个:

feline;labrador;bird;labrador retriever;labrador dog; lab dog;

对此:

feline;dog;bird;dog;dog;dog;

以下是我正在使用的正则表达式。我知道^表示字符串的开头,$表示结束。我尝试了很多变化,并且正在进行替换,但是没有实现我想要的输出。我还猜测一个正则表达式可以兼顾两者吗?谢谢大家的帮助。

df$variable <- gsub("^apt$;", "Apartment;", df$variable, ignore.case = TRUE)

2 个答案:

答案 0 :(得分:3)

这是一种使用后面的方法(所以你需要perl=TRUE):

> tmp <- c("feline;labrador;bird;labrador retriever;labrador dog; lab dog;",
+          "lab;feline;labrador;bird;labrador retriever;labrador dog; lab dog")
> gsub( "(?<=;|^) *lab[^;]*", "dog", tmp, perl=TRUE)
[1] "feline;dog;bird;dog;dog;dog;"   
[2] "dog;feline;dog;bird;dog;dog;dog"

(?<=;|^)是背后的外观,它表示任何匹配必须以分号或字符串的开头开头,但匹配的内容不包含在要替换的部分中。 *将匹配0或更多空格(因为您的示例字符串有一个案例,在分号和lab之间有空格。然后匹配文字lab后跟0或者除了分号以外的其他字符。因为*默认是贪婪的,所以这将匹配所有内容,但不包括'下一个分号或字符串的结尾。你还可以包括一个正数向前看(?=;|$)以确保它一直到下一个分号或字符串结尾,但在这种情况下*的贪婪会照顾到它。

您也可以使用非贪婪修饰符,然后强制匹配字符串或分号的结尾:

> gsub( "(?<=;|^) *lab.*?(?=;|$)", "dog", tmp, perl=TRUE)
[1] "feline;dog;bird;dog;dog;dog;"   
[2] "dog;feline;dog;bird;dog;dog;dog"

.*?将匹配0个或更多字符,但只能尽可能少,直到下一个分号或行尾。

如果匹配分隔符,您可以跳过后面的内容(和perl=TRUE),然后将其包含在替换中:

> gsub("(;|^) *lab[^;]*", "\\1dog", tmp)
[1] "feline;dog;bird;dog;dog;dog;"   
[2] "dog;feline;dog;bird;dog;dog;dog"

使用这种方法你需要注意,你只匹配一侧的分隔符(我的例子中的第一个),因为匹配消耗了分隔符(不是前瞻或后瞻),如果你同时使用这两个分隔符分隔符,然后将跳过下一个,并且只考虑每个其他字段进行替换。

答案 1 :(得分:1)

我建议分两步执行此操作:

  1. 按分隔符分割字符串
  2. 进行替换
  3. (可选,如果那就是你要做的事情)将琴弦重新粉碎。
  4. 要分割字符串,我会使用set userprofile=C:\Users\%username% aws configure set AWS_ACCESS_KEY_ID <your_key> aws configure set AWS_SECRET_ACCESS_KEY <your_secret> aws configure set default.region <your_region> other aws commands here 库。但你也可以使用基数R:

    stringr

    完成后,您可以进行文字替换:

     myString  <- "Apt;House;Condo;Apts;"
    
     # base R
     splitString  <- unlist(strsplit(myString, ";", fixed = T))
    
     # with stringr
     library(stringr)
     splitString  <- as.vector(str_split(myString, ";", simplify = T)) 
    

    可能有一种比正则表达式更好的替换方法(使用# base R fixedApts <- gsub("^Apt$|^Apts$", "Apartment", splitString) # with stringr fixedApts <- str_replace(splitString, "^Apt$|^Apts$", "Apartment") # then do the rest of your replacements ,也许?)

    如果您需要做什么,请使用switch()将矢量折叠为最后一个字符串。