我很难理解Ruby docs中的以下代码段:
a = "hello world"
a.count "lo" #=> 5
a.count "lo", "o" #=> 2
a.count "hello", "^l" #=> 4
a.count "ej-m" #=> 4
"hello^world".count "\\^aeiou" #=> 4
"hello-world".count "a\\-eo" #=> 4
尤其是此代码a.count "ej-m"
。任何人都可以解释它是如何工作的吗?
答案 0 :(得分:5)
想象一下由[
包裹的“模式”字符串和正则表达式语法中的]
,它们与每个字符匹配。
所以,如果我们将a = "hello world"
分成字符:
[1] pry(main)> a = "hello world"
=> "hello world"
[2] pry(main)> a.split('')
=> ["h", "e", "l", "l", "o", " ", "w", "o", "r", "l", "d"]
将“ej-m”转换为包含[
和]
的正则表达式,我们得到/[ej-m]/
- 这意味着'e'
或来自'j'
的任何字符到'm'
(包括两者):
[3] pry(main)> a.split('').select{|c| c=~ /[ej-m]/}
=> ["e", "l", "l", "l"]
我们有4场比赛 - 这也是你得到的结果。实际上a.count "ej-m"
相当于:
[4] pry(main)> a.split('').count{|c| c=~ /[ej-m]/}
=> 4
方法的多个参数在匹配项之间只有and
:
[5] pry(main)> a.split('').count{|c| c =~ /[hello]/ and c =~ /[^l]/}
=> 4
答案 1 :(得分:2)
The sequence c1-c2 means all characters between c1 and c2.
因此,您提供的是一个范围,基本上它会计算该范围内的哪些字符(> = c1&&< = c2)
即:
a = "hello world"
a.count "a-z"
=> 10
a.count "o-w"
=> 4 #(o, o, r, w)
a.count "e-l"
=> 5 #(h, e, l, l, l)
答案 2 :(得分:2)
我们找到了
"hello world".count("ej-m") #=> 4 (_ell_____l_)
仔细检查String#count的文档。
以下是count
如何实施以处理与模式"ej-m"
非常相似的模式。
def count_letters(str, pattern)
idx = pattern[1..-2].index('-')
if idx
idx += 1
before, after = pattern[idx-1], pattern[idx+1]
pattern[idx-1..idx+1] = (before..after).to_a.join
end
str.each_char.sum { |c| pattern.include?(c) ? 1 : 0 }
end
count_letters(str, pattern) #=> 4 (_ell_____l_)
但是,String#count
也必须执行以下操作。
允许模式中的多个范围
"hello1world".count("e0-9j-mv-x") #=> 6 (_ell__1_w__l_)
如果模式以字符'^'
开头,则计算与模式的其余部分不匹配的字符数
"hello world".count("^ej-m") #=> 7 (h___o*wor_d) * = space to count
"hello^world".count("e^j-m") #=> 5 (_ell_^___l_)
"hello world".count("\^ej-m") #=> 7 (h___o*wor_d) * = space to count
请注意,在字符串开头转义'^'
没有任何区别。
匹配连字符
"hello-world".count("ej-m-") #=> 5 (_ell_-___l_)
"hello-world".count("-ej-m") #=> 5 (_ell_-___l_)
"hello-world".count("ej\-m") #=> 4 (_ell____l_)
请注意,转义不是模式的第一个或最后一个字符的连字符没有区别。
匹配反斜杠
'hello\world'.count("ej-m\\") #=> 5 (_ell_\___l_)
'hello\world'.count("\\ej-m") #=> 4 (_ell____l_)
请注意,忽略字符串开头的反斜杠。
上述一些结果(Ruby v2.4)似乎与文档不一致。