如何在Ruby中将正则表达式的一部分捕获到变量中?

如何在Ruby中将正则表达式的一部分捕获到变量中?,ruby,Ruby,我知道“string”[/regex/],它返回字符串中匹配的部分。但是,如果我只想返回字符串的捕获部分,该怎么办 我有字符串“1952-FEB-21\u 70\u金戒指的盒子.mp3”。我想在变量title中存储文本黄金戒指的大小写 我可以用regex/\d_(?。*\d_419;)(.*.mp3$/I捕获这个部分。但是写Ruby“1952-FEB-21\u 70\u黄金戒指的盒子.mp3”[/\d(?).*\d(.*).mp3$/i]会返回0\u黄金戒指的盒子.mp3,这不是我想要的 我可以

我知道
“string”[/regex/]
,它返回字符串中匹配的部分。但是,如果我只想返回字符串的捕获部分,该怎么办

我有字符串
“1952-FEB-21\u 70\u金戒指的盒子.mp3”
。我想在变量
title
中存储文本
黄金戒指的大小写

我可以用regex
/\d_(?。*\d_419;)(.*.mp3$/I
捕获这个部分。但是写Ruby
“1952-FEB-21\u 70\u黄金戒指的盒子.mp3”[/\d(?).*\d(.*).mp3$/i]
会返回
0\u黄金戒指的盒子.mp3
,这不是我想要的

我可以通过写作得到我想要的

"1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3" =~ /\d_(?!.*\d_)(.*).mp3$/i
title = $~.captures[0]
但这似乎有些草率。肯定有一个合适的方法来做到这一点


(我知道有人可能会编写一个更简单的正则表达式来针对我想要的文本,让
“string”[/regex/]
方法工作,但这只是一个例子来说明问题,具体的正则表达式不是问题所在。)

看看
匹配
方法:

string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
regexp = /\d_(?!.*\d_)(.*).mp3$/i

matches = regexp.match(string)
matches[1]
#=> "The_Case_of_the_Gold_Ring"
=> string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 1]
=> "The_Case_of_the_Gold_Ring"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 0]
=> "0_The_Case_of_the_Gold_Ring.mp3"
其中
匹配[0]
将返回整个匹配,而
匹配[1]
(及以下)将返回所有子类别:

matches.to_a    
#=> ["0_The_Case_of_the_Gold_Ring.mp3", "The_Case_of_the_Gold_Ring"]

阅读更多示例:

查看
匹配方法:

string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
regexp = /\d_(?!.*\d_)(.*).mp3$/i

matches = regexp.match(string)
matches[1]
#=> "The_Case_of_the_Gold_Ring"
=> string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 1]
=> "The_Case_of_the_Gold_Ring"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 0]
=> "0_The_Case_of_the_Gold_Ring.mp3"
其中
匹配[0]
将返回整个匹配,而
匹配[1]
(及以下)将返回所有子类别:

matches.to_a    
#=> ["0_The_Case_of_the_Gold_Ring.mp3", "The_Case_of_the_Gold_Ring"]
阅读更多示例:

您可以使用命名捕获

“1952-FEB-21 \u 70 \u金戒指的盒子.mp3”=~/\d\u(?).*\d\u)(?*).mp3$/i
而且,
$~[:title]
将提供您想要的

您可以使用命名捕获

“1952-FEB-21 \u 70 \u金戒指的盒子.mp3”=~/\d\u(?).*\d\u)(?*).mp3$/i

并且,
$~[:title]
将提供您想要的

您可以将零件编号传递给
[/regexp/,index]
方法:

string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
regexp = /\d_(?!.*\d_)(.*).mp3$/i

matches = regexp.match(string)
matches[1]
#=> "The_Case_of_the_Gold_Ring"
=> string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 1]
=> "The_Case_of_the_Gold_Ring"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 0]
=> "0_The_Case_of_the_Gold_Ring.mp3"

您可以将零件编号传递给
[/regexp/,index]
方法:

string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
regexp = /\d_(?!.*\d_)(.*).mp3$/i

matches = regexp.match(string)
matches[1]
#=> "The_Case_of_the_Gold_Ring"
=> string = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 1]
=> "The_Case_of_the_Gold_Ring"
=> string[/\d_(?!.*\d_)(.*).mp3$/i, 0]
=> "0_The_Case_of_the_Gold_Ring.mp3"
思考这个问题:

下面是要分析的源字符串:

str = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
模式可以定义为字符串:

DATE_REGEX = '\d{4}-[A-Z]{3}-\d{2}'
SERIAL_REGEX = '\d{2}'
TITLE_REGEX = '.+'
然后插入到regexp中:

regex = /^(#{ DATE_REGEX })_(#{ SERIAL_REGEX })_(#{ TITLE_REGEX })/
# => /^(\d{4}-[A-Z]{3}-\d{2})_(\d{2})_(.+)/
这样做的好处是更容易维护,因为模式实际上是几个较小的模式

str.match(regex) # => #<MatchData "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3" 1:"1952-FEB-21" 2:"70" 3:"The_Case_of_the_Gold_Ring.mp3">
regex.match(str) # => #<MatchData "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3" 1:"1952-FEB-21" 2:"70" 3:"The_Case_of_the_Gold_Ring.mp3">
我们还可以命名捕获并像散列一样访问它们:

regex = /^(?<date>#{ DATE_REGEX })_(?<serial>#{ SERIAL_REGEX })_(?<title>#{ TITLE_REGEX })/
matches = regex.match(str)
matches[:date] # => "1952-FEB-21"
matches[:serial] # => "70"
matches[:title] # => "The_Case_of_the_Gold_Ring.mp3"
split
可以接受一个limit参数,该参数表示应该拆分字符串多少次。通过
3
我们可以:

str.split('_', 3) # => ["1952-FEB-21", "70", "The_Case_of_the_Gold_Ring.mp3"]
抓取最后一个元素将返回:

str.split('_', 3).last # => "The_Case_of_the_Gold_Ring.mp3"
思考这个问题:

下面是要分析的源字符串:

str = "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3"
模式可以定义为字符串:

DATE_REGEX = '\d{4}-[A-Z]{3}-\d{2}'
SERIAL_REGEX = '\d{2}'
TITLE_REGEX = '.+'
然后插入到regexp中:

regex = /^(#{ DATE_REGEX })_(#{ SERIAL_REGEX })_(#{ TITLE_REGEX })/
# => /^(\d{4}-[A-Z]{3}-\d{2})_(\d{2})_(.+)/
这样做的好处是更容易维护,因为模式实际上是几个较小的模式

str.match(regex) # => #<MatchData "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3" 1:"1952-FEB-21" 2:"70" 3:"The_Case_of_the_Gold_Ring.mp3">
regex.match(str) # => #<MatchData "1952-FEB-21_70_The_Case_of_the_Gold_Ring.mp3" 1:"1952-FEB-21" 2:"70" 3:"The_Case_of_the_Gold_Ring.mp3">
我们还可以命名捕获并像散列一样访问它们:

regex = /^(?<date>#{ DATE_REGEX })_(?<serial>#{ SERIAL_REGEX })_(?<title>#{ TITLE_REGEX })/
matches = regex.match(str)
matches[:date] # => "1952-FEB-21"
matches[:serial] # => "70"
matches[:title] # => "The_Case_of_the_Gold_Ring.mp3"
split
可以接受一个limit参数,该参数表示应该拆分字符串多少次。通过
3
我们可以:

str.split('_', 3) # => ["1952-FEB-21", "70", "The_Case_of_the_Gold_Ring.mp3"]
抓取最后一个元素将返回:

str.split('_', 3).last # => "The_Case_of_the_Gold_Ring.mp3"

我相信在这里使用捕获组是最容易的,但是为了说明的目的,我想介绍一些不可能的可能性。它们都采用相同的正向前瞻(
(?=\.mp3$)
)。除一个字符外,所有字符都使用正向查找,另一个字符使用
\K
来“忘记”所需匹配开始前的最后一个字符。有些允许匹配的字符串包含数字(
+
);其他人没有(
[^\d]

str=“1952-FEB-21\u 70\u金戒指的盒子。mp3”
1#匹配在最后一个数字后面,后跟下划线,不能包含数字
str[/(?“黄金戒指的案例”
2与1相同,因为“\K”忽略与该点的匹配
str[/\d\uk[^\d]+(?=\.mp3$)/]
#=>“金戒指的盒子”
3#匹配后跟下划线,两个数字下划线可能包含数字
str[/(?“黄金戒指的案例”
4#匹配跟随具有特定模式的字符串,可能包含数字
str[/(?“黄金戒指的案例”
5#匹配在数字、任意12个字符、另一个数字和下划线之后,
#可能包含数字
str[/(?“黄金戒指的案例”

我认为在这里使用捕获组是最简单的,但为了说明起见,我想介绍一些不可能的可能性。所有捕获组都使用相同的正向前瞻(
(?=\.mp3$)
)。除了一个捕获组外,其他所有捕获组都使用正向前瞻,而另一个捕获组使用
\K
来“忘记”匹配到所需匹配开始前的最后一个字符。有些允许匹配的字符串包含数字(
+
),有些则不允许(
[^\d]

str=“1952-FEB-21\u 70\u金戒指的盒子。mp3”
1#匹配在最后一个数字后面,后跟下划线,不能包含数字
str[/(?“黄金戒指的案例”
2与1相同,因为“\K”忽略与该点的匹配
str[/\d\uk[^\d]+(?=\.mp3$)/]
#=>“金戒指的盒子”
3#匹配后跟下划线,两个数字下划线可能包含数字
str[/(?“黄金戒指的案例”
4#匹配跟随具有特定模式的字符串,可能包含数字
str[/(?“黄金戒指的案例”
5#匹配在数字、任意12个字符、另一个数字和下划线之后,
#可能包含数字
str[/(?“黄金戒指的案例”