谁能给我解释一下?
str = "org-id: N/A\n"
puts str[/org-id:\s+(.+)\n/]
=> "org-id: N/A\n"
str =~ /org-id:\s+(.+)\n/
puts $1
=> "N/A"
我只需要
str =~ /org-id:\s+(.+)\n/
puts $1
在一行中。
但是 str[/org-id:\s+(.+)\n/]
和 str.slice(/org-id:\s+(.+)\n/)
返回 "org-id: N/A\n"
和 str.scan(/org-id:\s+(.+)\n/)。首先返回 ["N/A"]
(和数组)。为什么所有这些匹配的行为都不一样?
最佳答案
来自fine manual :
str[regexp] → new_str or nil
str[regexp, fixnum] → new_str or nilIf a
Regexp
is supplied, the matching portion of str is returned. If a numeric or name parameter follows the regular expression, that component of theMatchData
is returned instead.
所以,如果你这样做 str[/org-id:\s+(.+)\n/]
然后你得到整个匹配部分(AKA $&
);如果你想要第一个捕获组(AKA $1
),那么你可以说:
puts str[/org-id:\s+(.+)\n/, 1]
# 'N/A'
如果您的正则表达式中有第二个捕获组并且您想要它捕获的内容,您可以说 str[regex, 2]
等等。您还可以这样使用命名的捕获组和符号:
puts str[/org-id:\s+(?<want>.+)\n/, :want]
因此,使用正确的模式和参数,String#[]
方便从字符串中提取单个基于正则表达式的 block 。
如果您查看手册,您应该会注意到 String#[]
和 String#splice
是一样的。
如果我们看 String#=~
,我们看到:
str =~ obj → fixnum or nil
Match—If obj is a
Regexp
, use it as a pattern to match against str, and returns the position the match starts, ornil
if there is no match.
所以当你说:
str =~ /org-id:\s+(.+)\n/
你得到 'org-id: N/A'
在 $&
, 'N/A'
在 $1
,运算符的返回值为数字零;如果您的正则表达式中有另一个捕获组,您会在 $2
中看到该部分. nil
或nil
的返回值=~
允许你说这样的话:
make_pancakes_for($1) if(str =~ /some pattern that makes (us) happy/)
所以 =~
便于一次组合解析和 bool 测试。
String#scan
方法:
scan(pattern) → array
scan(pattern) {|match, ...| block } → strBoth forms iterate through str, matching the pattern (which may be a
Regexp
or aString
). For each match, a result is generated and either added to the result array or passed to the block. If the pattern contains no groups, each individual result consists of the matched string,$&
. If the pattern contains groups, each individual result is itself an array containing one entry per group.
所以 scan
如果涉及捕获组,则为您提供一个简单的匹配列表或匹配的 AoA 和 scan
旨在一次性将一个字符串分解成它的所有组成部分(有点像 String#split
的更复杂版本)。
如果您想获取所有 (.+)
匹配您将使用的字符串 scan
和 map
:
array_of_ids = str.scan(/org-id:\s+(.+)\n/).map(&:first)
但如果您知道 str
中会有多个组织 ID,您只会为此烦恼。 .扫描也会留下$&
, $1
, ... 设置为 scan
中最后一个匹配项的值;但如果你使用 scan
您将同时查找多个匹配项,因此这些全局变量不会非常有用。
三种正则表达式方法( []
、 =~
和 scan
)提供相似的功能,但它们填补了不同的空白。你可以用 scan
完成这一切但这将是毫无意义的麻烦,除非你是一个正交偏执狂,然后你肯定不会在 Ruby 中工作,除非在极端胁迫下,所以这无关紧要。
关于ruby - ruby 混淆中的正则表达式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10825366/