2016-03-07 43 views
0

我遇到了一個看似簡單的問題,但我找到的解決方案並不令人滿意。我想用逗號替換後面的數字。例如,替換數字後的句點

strings <- c("22.222.222", "12.323", "don.t replace") 

將被成功地轉化爲

[1] "22,222,222" "12,323"  "don.t replace" 

我嘗試的第一個解決方案是

str_replace_all(strings, 
       "(?<=\\d+)\\.", 
       ",") 

,但我得到了以下錯誤消息:

Error in stri_replace_all_regex(string, pattern, replacement, vectorize_all = vec, : 
Look-Behind pattern matches must have a bounded maximum length. (U_REGEX_LOOK_BEHIND_LIMIT) 

當我使用

str_replace_all(strings, 
      "(?<=\\d{1,3})\\.", 
      ",") 

我得到正確的轉換。然而,硬編碼的1-3位不是我想要的,我不明白爲什麼\\d+不起作用,但\\d{1,3}

+1

不是'「(?<= \\ d)\\。」'夠好嗎? – sgibb

+0

爲什麼你需要向前看?我的意思是你接受了一個前瞻解決方案的答案,而這實際上不是你在這裏需要的。在性能方面,後視是昂貴的(至少在模式開始時),你應該儘可能地避免它們。請注意,限制已經使用的子字符串的lookbehinds是有效的,但事實並非如此。 –

回答

2

不需要+量詞,你所關心的只是匹配序列中的最後一位數字。所以只需在\d的後面。

str_replace_all(strings, 
       "(?<=\\d)\\.", 
       ",") 
2

由於數字是已知的子模式,因此不需要任何替代方法,因此不需要任何重疊匹配。只需使用一個捕獲組圍繞數字和結果與反向引用恢復它們:

> library(stringr) 
> strings <- c("22.222.222", "12.323", "don.t replace") 
> str_replace_all(strings, "(\\d+)\\.", "\\1,") 
[1] "22,222,222" "12,323"  "don.t replace" 

或者與基礎R gsub

> gsub("(\\d+)\\.", "\\1,", strings) 
[1] "22,222,222" "12,323"  "don.t replace" 

regex demo

注意(?<=\\d{1,3})約束寬度後視工程,因爲stringr正則表達式的風格是ICU 。如果可以事先計算lookbehind中的模式長度,那麼它將起作用,因此限制量詞具有最小值和最大值都可以正常工作。它不適用於PCRE(perl=T)與gsub正則表達式。無限寬的lookbehind(內部有+*量詞)僅在少數幾個版本中受支持:Python PyPi正則表達式模塊,.NET,RegexBuddy工具,Vim。