【发布时间】:2016-06-10 07:57:48
【问题描述】:
"abc def" 应该匹配下面的正则表达式,因为 "abc" 和 "def" 都有 3 个字符
/([a-z]*) ([a-z]*){\1.length}/
有没有办法在 Ruby 中做到这一点?
【问题讨论】:
-
必须是正则表达式解决方案吗?
-
@Mark 是的,这样会更好
"abc def" 应该匹配下面的正则表达式,因为 "abc" 和 "def" 都有 3 个字符
/([a-z]*) ([a-z]*){\1.length}/
有没有办法在 Ruby 中做到这一点?
【问题讨论】:
您描述的字符串集不构成常规语言。它不能被正则表达式匹配。这是无法用正则表达式匹配的语言的经典示例之一(另一个是测试匹配括号)。
在普通代码中比较两个字符串的长度即可。
【讨论】:
不,不是单独使用正则表达式。部分:{\1.length} 无效,至少,不像您希望使用的那样。
试试这样的:
#!/usr/bin/env ruby
if /([a-z]+)\s+([a-z]+)/ =~ 'abc def' and $1.length == $2.length
print 'OK'
else
print 'No match...'
end
【讨论】:
def match_equal_length(s, regex)
m = s.scan(r)
return m[0] if (m.size > 0) && (m[0][0].size == m[0][1].size)
nil # String doesn't match or $1.size != $2.size
end
【讨论】:
我认为你不能在正则表达式中做到这一点,但你可以通过使用带有 match 的块来非常接近:
two_same_length = s.match(/([a-z]*) ([a-z]*)/) { |m| m[1].length == m[2].length }
整场比赛都在m[0] in the block,你想看看分组所以你想要m[1]和m[2]。如果您总是想要一个布尔值(而不是 nil,如果根本没有匹配项),那么双敲它:
two_same_length = !!s.match(/([a-z]*) ([a-z]*)/) { |m| m[1].length == m[2].length }
例如:
>> !!'abc pancakes'.match(/([a-z]*) ([a-z]*)/) { |m| m[1].length == m[2].length }
=> false
>> !!'pancakes'.match(/([a-z]*) ([a-z]*)/) { |m| m[1].length == m[2].length }
=> false
>> !!'whereis pancake'.match(/([a-z]*) ([a-z]*)/) { |m| m[1].length == m[2].length }
=> true
【讨论】: