ruby - ruby 混淆中的正则表达式匹配

标签 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/) 返回 "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 nil

If a Regexp is supplied, the matching portion of str is returned. If a numeric or name parameter follows the regular expression, that component of the MatchData 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, or nil if there is no match.

所以当你说:

str =~ /org-id:\s+(.+)\n/

你得到 'org-id: N/A'$& , 'N/A'$1 ,运算符的返回值为数字零;如果您的正则表达式中有另一个捕获组,您会在 $2 中看到该部分. nilnil 的返回值=~允许你说这样的话:

make_pancakes_for($1) if(str =~ /some pattern that makes (us) happy/)

所以 =~便于一次组合解析和 bool 测试。


String#scan 方法:

scan(pattern) → array
scan(pattern) {|match, ...| block } → str

Both forms iterate through str, matching the pattern (which may be a Regexp or a String). 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/

相关文章:

java - 如何将 Java 中的此 SHA 函数转换为 Ruby 中的等效函数?

ruby-on-rails - 无法通过 Post 在 Rspec 中创建模型

ruby - ruby gem 'gamebox' 的“捆绑”问题

regex - 如何制作可移植正则表达式?

ruby-on-rails - 在 Ruby/Rails 中处理大型数据集导入

json - 正则表达式可以减少巨大的文件大小?

regex - 正则表达式的大写单词

c - 如何传递指向字符串的指针、指向子字符串的指针并返回其他内容?

c# - 将列表转换为数字范围字符串

python - 如何给包含字母的字符串加+1?