2012-11-28 31 views
7

我有以下正則表達式,我想抓住從句子開頭到第一個##的所有內容。我可以使用strsplit來演示如何執行此任務,但我更喜歡gsub解決方案。如果gusub不是正確的工具(我認爲它是)但我更喜歡基礎解決方案,因爲我想學習基礎正則表達式工具。從gsub開始抓取字符首先出現

x <- "gfd gdr tsvfvetrv erv tevgergre ## vev fe ## vgrrgf" 

strsplit(x, "##")[[c(1, 1)]] #works 

gsub("(.*)(##.*)", "\\1", x) #I want to work 

回答

13

只需添加一個角色,把一個?第一量詞後,使其「非貪婪」:

gsub("(.*?)(##.*)", "\\1", x) 
# [1] "gfd gdr tsvfvetrv erv tevgergre " 

這裏的相關文件,從?regex

默認情況下,重複是貪婪的,因此使用的 重複的最大可能數。可以通過追加 '?'將其更改爲'minimal'給量詞。

+0

感謝您提供'gsub'解決方案並解釋我的想法出了什麼問題。 +1 –

1

在字符串的開頭試試這個作爲你的正則表達式

^[^#]+ 

啓動並匹配任何不是#到第一#

4

我會說:

sub("##.*", "", x) 

刪除包括和第一次發生0123後的所有內容。

+0

偉大的工程和第一個解決方案。謝謝。 +1 –

3

在這種情況下,我會說的倒數,即取代一切與一個空字符串以下#

gsub("#.*$", "", x) 
[1] "gfd gdr tsvfvetrv erv tevgergre " 

但你也可以使用非貪婪修改?,使您的正則表達式工作你的方式建議:

gsub("(.*?)#.*$", "\\1", x) 
[1] "gfd gdr tsvfvetrv erv tevgergre " 
+0

謝謝。這是我要求的第一個'gsub'解決方案。 +1 –

1

有幾個簡單的答案已經在這裏,但因爲你在你的問題表明您想了解有關基礎R正則表達式的支持,還有一種方法,使用正預測先行斷言(?=#)和非貪婪選項(?U)

regmatches(x, regexpr('(?U)^.+(?=#)', x, perl=TRUE)) 
[1] "gfd gdr tsvfvetrv erv tevgergre " 
+0

感謝您花時間添加更多正則表達式的使用。我只用了幾次'regmatches',但那是很大的幫助。謝謝。+1 –

1

這是另一種使用更多字符串工具而不是更復雜的正則表達式的方法。它首先找到的第##的位置,然後提取子到這一點:

library(stringr) 
x <- "gfd gdr tsvfvetrv erv tevgergre ## vev fe ## vgrrgf" 
loc <- str_locate(x, "##") 
str_sub(x, 1, loc[, "start"] - 1) 

一般情況下,我認爲這種一步一步的做法是不是複雜的正則表達式更容易維護。

+0

我注意到你在之前的帖子中也推薦了一步法。這種方法(特別是少量文本)通常更易於管理。 +1 –