Ruby和正则表达式的问题非常奇怪

时间:2010-02-15 16:49:08

标签: ruby regex

我从string.scan和几个正则表达式测试者那里获得完全不同的结果......

我只是想从字符串中抓取域名,这是最后一个字。

有问题的正则表达式:

/([a-zA-Z0-9\-]*\.)*\w{1,4}$/

字符串(1个单行,在Ruby的运行时btw中验证)

str = 'Show more results from software.informer.com'

工作正常,但是红宝石......

irb(main):050:0> str.scan /([a-zA-Z0-9\-]*\.)*\w{1,4}$/
=> [["informer."]]

我认为我会在software.informer.com上找到匹配,这是我的目标。

4 个答案:

答案 0 :(得分:3)

你的正则表达式是正确的,结果与String#scan行为的方式有关。来自the official documentation

“如果模式包含组,则每个单独的结果本身就是一个包含每个组一个条目的数组。”

基本上,如果你在整个正则表达式中放置括号,结果中每个数组的第一个元素将是你所期望的。

答案 1 :(得分:2)

您在software.informer.com上获得了匹配。检查$&的值。 scan的返回是捕获的组的数组。在后缀周围添加捕获括号,您将.com作为scan的返回值的一部分。

正则表达式测试人员和Ruby对基本问题(正则表达式本身)没有异议。相反,他们的界面在他们强调的方面有所不同。当您在scan中运行irb时,您将看到的第一件事是来自scan(捕获的子图案的数组)中的返回值,这是与匹配的文本不同。正则表达式测试人员最有可能面向显示匹配的文本。

答案 2 :(得分:2)

看起来好像不期望有多个结果(特别是当正则表达式被锚定时)。在这种情况下,没有理由使用扫描。

'Show more results from software.informer.com'[ /([a-zA-Z0-9\-]*\.)*\w{1,4}$/ ]
#=> "software.informer.com"

如果您确实需要使用扫描(在这种情况下您显然需要删除锚点),您可以使用(?:)创建非捕获组。

'foo.bar.baz lala software.informer.com'.scan( /(?:[a-zA-Z0-9\-]*\.)*\w{1,4}/ )
#=> ["foo.bar.baz", "lala", "software.informer.com"]

答案 3 :(得分:0)

这样做:

/([a-zA-Z0-9\-]*\.*\w{1,4})$/

返回

informer.com

在测试字符串上。

http://rubular.com/regexes/13670