2012-08-31 124 views
10

我在R中使用正則表達式有一個奇怪的請求。我有一些字符串的向量,其中一些有多個尾隨句點。我想用空格替換這些句點。這個例子和期望的結果應該清楚我是什麼之後(也許我需要什麼,我給更換的說法,而不是gsub的模式參數來攻擊它):用空格替換尾隨句號

實例和嘗試:

x <- c("good", "little.bad", "really.ugly......") 
gsub("\\.$", " ", x) 
    #produces this 
    #[1] "good"    "little.bad"  "really.ugly..... " 
gsub("\\.+$", " ", x) 
    #produces this 
    #[1] "good"   "little.bad" "really.ugly " 

期望的結果

[1] "good"    "little.bad"  "really.ugly  " 

所以原來的向量(x)是具有與在最後6個週期的最後一個字符串所以我想6溫泉沒有觸及真正和醜陋之間的時期。我知道$看起來最終,但無法超越這一點。

回答

16

試試這個:

gsub("\\.(?=\\.*$)", " ", mystring, perl=TRUE) 

說明:

\. # Match a dot 
(?= # only if followed by 
\.* # zero or more dots 
$ # until the end of the string 
) # End of lookahead assertion. 
+0

我得到'無效的正則表達式'。(?= \。* $)',原因'無效的正規表達式' –

+0

@DavidRobinson:在一個字符串中,你需要加兩個反斜槓。 –

+2

+1我編輯你的答案,以顯示它如何轉化爲R. – Andrie

2

雖然我等了一個正則表達式的解決方案,是有道理的,我決定拿出來解決這個荒謬的方式:

messy.sol <- function(x) { 
paste(unlist(list(gsub("\\.+$", "", x), 
    rep(" ", nchar(x) - nchar(gsub("\\.+$", "", x))))),collapse="") 
} 

sapply(x, messy.sol, USE.NAMES = FALSE) 

我會說蒂姆的有點漂亮:)

+0

+1只要它有效;) –

2

蒂姆的解決方案顯然更好,但我想我會嘗試另一種方式。使用regmatches自由使用可以幫助我們在這裏

x <- c("good", "little.bad", "really.ugly......") 
# Get an object with 'match data' to feed into regmatches 
# Here we match on any number of periods at the end of a string 
out <- regexpr("\\.*$", x) 

# On the right hand side we extract the pieces of the strings 
# that match our pattern with regmatches and then replace 
# all the periods with spaces. Then we use assignment 
# to store that into the spots in our strings that match the 
# regular expression. 
regmatches(x, out) <- gsub("\\.", " ", regmatches(x, out)) 
x 
#[1] "good"    "little.bad"  "really.ugly  " 

所以不是很乾淨的一個正則表達式。但是我從來沒有真正瞭解perl正則表達式中的這些'前瞻'。

+0

不像Tim的那麼幹淨,但仍然是一個很好的解決方案(特別是與我自己相比)。 +1 –