2016-11-11 67 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