ruby混乱中的正则表达式匹配

ruby混乱中的正则表达式匹配,ruby,regex,string,string-matching,Ruby,Regex,String,String Matching,谁能给我解释一下吗 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/)re

谁能给我解释一下吗

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/)
return
“org id:n/A\n”
和str.scan(/org id:\s+(.+)\n/)。首先返回
[“n/A”]
(和数组)。为什么所有这些匹配行为都不同?

这是匹配和捕获之间的区别。Str[regex]返回与整个正则表达式匹配的整个片段$1仅表示第一个()子句捕获的匹配部分。

来自:

str[regexp]→ 新建或无
str[regexp,fixnum]→ 新建或无

如果提供了
Regexp
,则返回str的匹配部分。如果正则表达式后面有数值或名称参数,则返回
MatchData
的该组件

因此,如果您执行
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]
您在
$和
中获得
'org-id:N/A'
'N/A'
$1
中,运算符的返回值为零;如果您的正则表达式中有另一个捕获组,您将在
$2
中看到该部分。
=
的“
nil
或not
nil
”返回值允许您说出以下内容:

make_pancakes_for($1) if(str =~ /some pattern that makes (us) happy/)
因此,
=~
可以方便地一次性组合解析和布尔测试


方法:

扫描(模式)→ 数组
扫描(模式){匹配,{块}→ str

这两种形式都通过str进行迭代,匹配模式(可能是
Regexp
String
)。对于每个匹配,将生成一个结果,并将其添加到结果数组或传递到块。如果模式不包含组,则每个单独的结果都由匹配的字符串
$&
组成。如果模式包含组,则每个单独的结果本身就是一个数组,每个组包含一个条目

因此,
scan
为您提供了一个简单的匹配列表或一个匹配AoA(如果涉及到捕获组),
scan
旨在一次性将字符串拆分为其所有组成部分(有点像更复杂的版本)

如果要从字符串中获取所有的
(.+)
匹配项,可以使用
scan
和:

但是,如果您知道在
str
中会有几个组织ID,那么您只会为此烦恼。扫描还将留下
$&
$1
。。。设置为
扫描中最后一次匹配的值
;但是如果您使用的是
scan
,您将同时查找多个匹配项,因此这些全局搜索项不会非常有用


三种正则表达式方法(
[]
=~
扫描
)提供了类似的功能,但它们填补了不同的领域。你可以用
scan
来完成这一切,但那将是毫无意义的麻烦,除非你是一个正交偏执狂,那么你肯定不会在Ruby中工作,除非是在极端的胁迫下,所以这并不重要

make_pancakes_for($1) if(str =~ /some pattern that makes (us) happy/)
array_of_ids = str.scan(/org-id:\s+(.+)\n/).map(&:first)