2015-02-10 66 views
-1

所以前段时间我在PHP中创建了一个函数,它允许我“twitterize”通过Twitter的API提取的推文文本。gsub可用于多种模式和多种替换

这里是什么样子:

function twitterize($tweet){ 
$patterns = array ("/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w][email protected])?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w][email protected])[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/", 
        "/(?<=^|(?<=[^a-zA-Z0-9-\.]))@([A-Za-z_]+[A-Za-z0-9_]+)/", 
        "/(?<=^|(?<=[^a-zA-Z0-9-\.]))#([A-Za-z_]+[A-Za-z0-9_]+)/"); 
$replacements = array ("<a href='\\0' target='_blank'>\\0</a>", "<a href='http://twitter.com/\\1' target='_blank'>\\0</a>", "<a href='http://twitter.com/search?q=\\1&src=hash' target='_blank'>\\0</a>"); 

return preg_replace($patterns, $replacements, $tweet); 

} 

现在我有点坚持使用Ruby的gsub,我想:

def twitterize(text) 
patterns = ["/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w][email protected])?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w][email protected])[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/", "/(?<=^|(?<=[^a-zA-Z0-9-\.]))@([A-Za-z_]+[A-Za-z0-9_]+)/", "/(?<=^|(?<=[^a-zA-Z0-9-\.]))#([A-Za-z_]+[A-Za-z0-9_]+)/"] 
replacements = ["<a href='\\0' target='_blank'>\\0</a>", 
       "<a href='http://twitter.com/\\1' target='_blank'>\\0</a>", 
       "<a href='http://twitter.com/search?q=\\1&src=hash' target='_blank'>\\0</a>"] 

return text.gsub(patterns, replacements) 
end 

这显然没有工作,返回了一个错误:

No implicit conversion of Array into String 

而在看了Ruby documentation on gsub并探索了几个他们提供的例子,我仍然无法找到我的问题的解决方案:有gsub一次处理多个模式和多个替换

帮助? :)

+0

任何人都在意解释你为什么低估这个问题? – 2015-02-10 03:15:05

回答

1

那么,你可以从文档中读取,gsub不是一次处理多个模式和替换。这就是导致你的错误,否则很明显(你可以读为“给我一个字符串,而不是阵列!! 1”)。

你可以写这样的:

def twitterize(text) 
    patterns = [/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w][email protected])?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w][email protected])[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/, /(?<=^|(?<=[^a-zA-Z0-9-\.]))@([A-Za-z_]+[A-Za-z0-9_]+)/, /(?<=^|(?<=[^a-zA-Z0-9-\.]))#([A-Za-z_]+[A-Za-z0-9_]+)/] 
    replacements = ["<a href='\\0' target='_blank'>\\0</a>", 
      "<a href='http://twitter.com/\\1' target='_blank'>\\0</a>", 
      "<a href='http://twitter.com/search?q=\\1&src=hash' target='_blank'>\\0</a>"] 

    patterns.each_with_index do |pattern, i| 
    text.gsub!(pattern, replacements[i]) 
    end 

    text 
end 

这可以被重构到更优雅rubyish代码,但我认为它会做的工作。

+0

好的谢谢,我真的很惊讶gsub不处理多种模式。我只是认为我没有正确理解文档。 谢谢! – 2015-02-10 03:36:29

+0

不客气;) – dgilperez 2015-02-10 03:36:56

0

错误是因为您试图在gsub函数中使用字符串位置处的替换数组。它的语法是

text.gsub(matching_pattern,replacement_text)

所以,你需要做这样的事情在红宝石

replaced_text = text.gsub(pattern1, replacement1) 
replaced_text = replaced_text.gsub(pattern2, replacement2) 

等。模式1是您的匹配模式之一,替换是您想要的替换文本。

干杯。

+0

哇,相比于PHP,第一次的红宝石让我失望。它一定会工作,谢谢! – 2015-02-10 03:37:55