如何在Crystal lang中以字符串值访问.match结果

时间:2018-07-18 00:47:53

标签: regex matching crystal-lang

在许多其他编程语言中,有一个函数将正则表达式作为参数并返回字符串值数组。 Javascript和Ruby都是如此。但是,晶体中的.match不会1)似乎不接受全局标志,并且2)它不返回数组,而是返回类型Regex::MatchData的结构。 (https://crystal-lang.org/api/0.25.1/Regex/MatchData.html

作为示例,以下代码:

str = "Happy days"
re = /[a-z]+/i
matches = str.match(re)
puts matches

返回Regex::MatchData("Happy")

我不确定如何将结果转换为字符串,或者为什么它不是默认值,因为它不是灵感语言(Ruby)中的默认值。我知道这个问题可能是由于我对结构和编译语言缺乏经验造成的,但我希望得到一个答案,希望它也可以帮助其他来自JS / Ruby背景的人。

2 个答案:

答案 0 :(得分:3)

  

如果我只想第一个匹配项转换为字符串怎么办?

puts "Happy days"[/[a-z]+/i]?
puts "Happy days".match(/[a-z]+/i).try &.[0]

它将尝试将字符串与/[a-z]+/i正则表达式进行匹配,如果存在匹配项,则将输出组0,即整个匹配项。请注意,如果找不到匹配项,则?之后的[...]将使其正常失败。如果仅使用puts "??!!"[/[a-z]+/i],则会引发异常。

请参见this online demo

如果您希望使用类似于String#scan的功能来返回在输入中找到的所有匹配项,则可以使用(根据@Amadan's remark仅保留缩短的版本):

matches = str.scan(re).map(&.string)

code above的输出:

["Happy days", "Happy days"]

请注意:

答案 1 :(得分:0)

实际上,发布的示例在Ruby中返回了#<MatchData "Happy">,它也没有“全局”标志-这就是String#scan(Regex)的用途,正如其他人所提到的。

如果您只想进行单次比赛而不经过Regex::MatchData,则可以使用String#[](Regex)

str = "Happy days"
p str[/[a-z]+/i] # => "Happy"