Ruby gsub的正则表达式!与锚点不匹配

时间:2014-12-03 01:06:22

标签: ruby regex

以下正则表达式应该在Ruby中有效,但它并不适用。 有关如何修复它的任何想法,所以它可以在循环中的.gsub!语句中使用吗?

textfield.gsub!( /(http:\/\/){0}www\./, 'http://www.' )

{0}应该允许第一部分匹配零次,但它不会:

'http://www.company1.com
 http://www.company2.com'.gsub!( /(http:\/\/){0}www\./, 'http://www.' )

=> " http://http://www.company1.com      http://http://www.company2.com

在此示例中,正则表达式不匹配,并保持输入字符串不被修改!

关于如何使这项工作的任何想法?

这看起来像Ruby的正则表达式处理中的错误

我承认我试图慷慨地解释{n}的语义以包含n = 0:)

2 个答案:

答案 0 :(得分:1)

问题是/(http:\/\/){0}/匹配任何字符串的开头。实际上,/(x){0}/将匹配x的任何值的任何字符串的开头。这个正则表达式表示我们应该发现x零次。好吧,我们可以在任意两个字符之间找到x零次。

你想要的是字符串开头字符^,后跟负向前瞻断言(?!...)。这允许您匹配不以特定字符序列开头的字符串。

'http://www.example.com'.gsub(/^(?!http:\/\/)www\./, 'http://www.')
# => 'http://www.example.com'

'www.example.com'.gsub(/^(?!http:\/\/)www\./, 'http://www.')
# => 'http://www.example.com'

答案 1 :(得分:1)

好像你需要将捕获组作为可选项。

> 'http://www.example.com'.gsub(/(http:\/\/)?www\./, 'http://www.')
=> "http://www.example.com"
> 'www.example.com'.gsub(/(http:\/\/)?www\./, 'http://www.')
=> "http://www.example.com"

(http:\/\/)?匹配字符串http://零次或一次。

你也可以使用负面的lookbehind。

> 'www.example.com'.gsub(/(?<!http:\/\/)www\./, 'http://www.')
=> "http://www.example.com"

此处应该进行替换,因为字符串www.不在http://之后。

> 'http://www.example.com'.gsub(/(?<!http:\/\/)www\./, 'http://www.')
=> "http://www.example.com"

此处替换不会发生,因为字符串www.前面有http://。因此解释器返回原始输入字符串而不做任何修改。