首先,在Ruby中编写时要小心用Perl语言思考。为了使代码更具可读性,我们做了一些更加细致的事情。
我会写my @extractArray = $string =~ m{the (.*?) fox .*?the (.*?) dog};
为:
string = "the quick brown fox jumps over the lazy dog."
string[/the (.*?) fox .*?the (.*?) dog/]
extract_array = $1, $2
# => ["quick brown", "lazy"]
红宝石,如Perl,意识到了capture groups的,并将其分配给值$1
,$2
等。这些敛值时,使得它非常干净,清晰并在稍后分配它们。正则表达式引擎允许您创建和分配命名捕获,但它们往往会掩盖发生的事情,所以为了清楚起见,我倾向于这样。
我们可以使用match
到那里太:
/the (.*?) fox .*?the (.*?) dog/.match(string) # => #<MatchData "the quick brown fox jumps over the lazy dog" 1:"quick brown" 2:"lazy">
,但最终的结果更具可读性?
extract_array = /the (.*?) fox .*?the (.*?) dog/.match(string)[1..-1]
# => ["quick brown", "lazy"]
命名捕获有趣太:
/the (?<quick_brown>.*?) fox .*?the (?<lazy>.*?) dog/ =~ string
quick_brown # => "quick brown"
lazy # => "lazy"
却致使想知道这些变量初始化和分配; I肯定不会在正则表达式中看到这些发生,所以它可能会让其他人感到困惑,并再次成为维护问题。
卡里说:
To elaborate a little on named captures, if match_data = string.match /the (?.?) fox .?the (?.*?) dog/, then match_data[:quick_brown] # => "quick brown" and match_data[:lazy] # => "lazy" (as well as quick_brown # => "quick brown" and lazy # => "lazy"). With named captures available, I see no reason for using global variables or Regexp.last_match, etc.
是的,但有一些气味也有。
我们可以用values_at
与match
的MatchData结果来获取捕获的值,但也有在课堂上的一些直观的行为,把我关:
/the (?<quick_brown>.*?) fox .*?the (?<lazy>.*?) dog/.match(string)['lazy']
作品,并暗示MatchData知道如何像一个哈希:
{'lazy' => 'dog'}['lazy'] # => "dog"
,它有一个values_at
方法,像哈希,但它并没有直观地工作:
/the (?<quick_brown>.*?) fox .*?the (?<lazy>.*?) dog/.match(string).values_at('lazy') # =>
# ~> -:6:in `values_at': no implicit conversion of String into Integer (TypeError)
鉴于:
/the (?<quick_brown>.*?) fox .*?the (?<lazy>.*?) dog/.match(string).values_at(2) # => ["lazy"]
现在就像一个数组:
['all captures', 'quick brown', 'lazy'].values_at(2) # => ["lazy"]
我想一致性,这使我的头不疼。
发现s.match(/ fox(。*?)dog /)[1]'方法存在问题。如果找不到匹配项,Ruby 2.1会抛出一个“未定义的方法'[]”错误。例如,将其更改为's.match(/ fox(。*?)cat /)[1]',它会窒息。 –
@ AlanW.Smith,我更新了答案。 '(s.match(/ fox(。*?)cat /)|| [])[1]' – falsetru