2016-11-11 33 views
1

我的字符串看起來像下面顯示的a。我需要提取第一個//和第一個後續/之間的部分字符串。我使用subperl = F,但它大約比perl = T慢4倍。所以我試着perl = T,發現搜索從字符串的END開始?R子與Perl - 開始向後搜索?

a = "https://moo.com/meh/woof//A.ds.serving/hgtht//ghhg/tjtke" 
    print(gsub(".*//(.*?)/.*","\\1",a)) 

    "moo.com" 

    print(gsub(".*//(.*?)/.*","\\1",a,perl=T)) 

    "ghhg" 

moo.com是我所需要的。我很驚訝地看到這一點 - 是否記錄在某處?我怎樣才能用perl重寫它 - 我有20M行可以使用,速度很重要。謝謝!

編輯:它沒有考慮到每個字符串將開始與http

+0

你知道包'urltools'嗎?在這些任務中派上用場 – Sotos

+0

對於TRE正則表達式,將惰性量詞與貪婪的量詞混合並不是一個好主意。在某些情況下,他們按預期工作,而在其他情況下,他們不會。在這種情況下使用'perl = TRUE',並且要記住'。*'儘可能匹配儘可能多的字符,'。*?'匹配儘可能少的字符,但'perl = TRUE',不符合換行符號。如果你需要,在模式開始處添加'(?s)'。 –

回答

1

你可以嘗試.*?//(.*?)/.*使第一.*懶惰太讓//將匹配第一個//實例:

gsub(".*?//(.*?)/.*","\\1",a,perl=T) 
# [1] "moo.com" 

而且?gsub說:

標準正則表達式代碼已被報告爲ve ry slow 適用於極長的字符串(數以萬計的 個字符或更多)時:perl = TRUE時使用的代碼看起來要快得多 並且對於此類用法更可靠。

gsub的標準版本不能正確替代重複的 字邊界(例如pattern =「\ b」)。對於這樣的 匹配使用perl = TRUE。

+0

謝謝!但爲什麼'perl = F'和'T'具有這種不同的行爲? –

+0

這是一個很好的問題。其實我不確定,目前找不到任何文檔。我認爲這與'gsub'函數的工作方式有關。 – Psidom