2016-12-29 53 views
1

我意識到這是一個相當簡單的問題定義邊界和我已經搜索整個網站,但似乎無法讓我的語法正確以下的正則表達式的挑戰。我期待着做兩件事。首先有正則表達式拿起前三個字符,並以分號停止。例如,我的字符串可能如下:正則表達式 - 用文字和分隔符

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) 
+1

你想替換整個單詞嗎?使用單詞邊界。 'gsub(「\\ bapt \\ b」,「Apartment」,df $ variable,ignore.case = TRUE)'。或者您是否需要專門替換分號和字符串的開始/結尾之間的子字符串? –

+0

我認爲你應該刪除正則表達式並使用面向字符串的函數。 –

+0

Hi @WiktorStribiżew,我正在尋找替換分號之間的子串以及字符串前面的單詞。爲了詳細說明第二個例子,可以用許多不同的方式發佈拉布拉多,包括拉布拉多獵犬,拉布拉多犬,實驗室狗等。總之,我需要創建正則表達式,以識別開始時的前三個字符和結束時的分隔符。希望這是有道理的。謝謝。 – BlueDevilPride

回答

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" 

有了這個方法,你必須要小心,你只能在一個匹配的分隔符(我的例子中是第一個),因爲匹配會消耗分隔符(而不是前瞻或後退),如果你使用了兩個分隔符,那麼下一個將被跳過,並且只有每隔一個字段纔會被替換。

+0

這是輝煌的,完美的作品@Greg Snow!謝謝!不知道看後面。欣賞您提供此解決方案的時間。 – BlueDevilPride

1

我會分兩步推薦這樣做:

  1. 分割字符串由分隔符
  2. 完成替換
  3. (可選,如果這是你必須做什麼)砸爛串起來。

要分割字符串,我會使用stringr庫。但是你可以使用基礎R太:

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 

有probabably一個更好的方式做比正則表達式替換(使用switch(),也許?)

使用paste0(fixedApts, collapse = "")在最後如果這是你需要做的事情將矢量摺疊成單個字符串。