我有一个数组:arr=[x1, x2, x3...]
和一个函数,它根据arr
中的第一个x
返回一个值,表明该函数为真.
本质上:
# my_x is the return of func()
# with the first x in arr that func(x) is true
# and the entire arr array is not processed.
my_x=arr.ruby_magic{|x| func(x) }
my_x should be equal to first true value return of func(x)
假设arr
中的每个X
都是正则表达式模式.不必运行每个正则表达式,我希望从第一场比赛中返回捕获组.
在Python语言中,我会用next
编写一个生成器.它将运行每个谓词,直到真返回,然后将该值传递给m
.如果没有真返回,则使用None
作为缺省值,但缺省值可以是任何值:
import re
patterns=[r"no match", r": (Value.*?pref)", r": (Value.*)", r"etc..."]
s="""
This is the input txt
This is a match if the other is not found: Value 1
This is the match I am looking for first: Value 1 pref
Last line.
"""
val_I_want=next(
(m.group(1) for p in patterns
if (m:=re.search(rf'{p}', s))), None)
我还没有在Ruby中找到对应的代码.
我可以做一个显式循环:
# s in the same multiline string as above...
patterns=[/no match/, /: (Value.*?pref)/, /: (Value.*)/,/etc.../]
val_I_want=nil
patterns.each{|p|
m=p.match(s)
if m then
val_I_want=m[1]
break
end
}
# val_I_want is either nil or
# the first match capture group that is true
这就是我想要的功能,但与Python生成器相比,这似乎有点冗长.
我已经try 了grep
,第一个值是谓词.但这里的问题是,entire结果数组是在使用next
之前生成的:
patterns.grep(proc {|p| p.match(s)}) {|m| m.match(s)[1]}.to_enum
# can then use .next on that.
#BUT it runs though the entire array when all I want is the first
#<Enumerator: ["Value 1 pref", "Value 1"]:each>
我try 了find
,但返回的第一个模式为真,而不是捕获组:
> e=patterns.find{|p| p.match(s) }
=> /: (Value.*?pref)/
# Now I would have to rerun match with the pattern found to get the text
pip ?