如果您需要捕获组来进行复杂的模式匹配,但又想要.scan 返回的整个表达式,这可以为您工作。
假设您想从带有 html 图片标签的 markdown 文本中获取此字符串中的图片网址:
str = %(
Before
<img src="https://images.zenhubusercontent.com/11223344e051aa2c30577d9d17/110459e6-915b-47cd-9d2c-1842z4b73d71">
After
<img src="https://user-images.githubusercontent.com/111222333/75255445-f59fb800-57af-11ea-9b7a-a235b84bf150.png">).strip
您可能定义了一个正则表达式以仅匹配 url,并且可能使用 Rubular example like this 来构建/测试您的 Regexp
image_regex =
/https\:\/\/(user-)?images.(githubusercontent|zenhubusercontent).com.*\b/
现在您不需要每个子捕获组,而只需要 .scan 中的整个表达式,您可以将整个模式包装在捕获组中并像这样使用它:
image_regex =
/(https\:\/\/(user-)?images.(githubusercontent|zenhubusercontent).com.*\b)/
str.scan(image_regex).map(&:first)
=> ["https://user-images.githubusercontent.com/1949900/75255445-f59fb800-57af-11ea-9b7a-e075f55bf150.png",
"https://user-images.githubusercontent.com/1949900/75255473-02bca700-57b0-11ea-852a-58424698cfb0.png"]
这实际上是如何工作的?
由于您有 3 个捕获组,仅 .scan 将返回一个数组 Array,每个捕获一个:
str.scan(image_regex)
=> [["https://user-images.githubusercontent.com/111222333/75255445-f59fb800-57af-11ea-9b7a-e075f55bf150.png", "user-", "githubusercontent"],
["https://images.zenhubusercontent.com/11223344e051aa2c30577d9d17/110459e6-915b-47cd-9d2c-0714c8f76f68", nil, "zenhubusercontent"]]
由于我们只想要第一个(外部)捕获组,我们可以调用.map(&:first)