在许多其他编程语言中,有一个函数将正则表达式作为参数并返回字符串值数组。 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背景的人。
答案 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"]
请注意:
String::scan
将为每个匹配项返回一个Regex::MatchData
的数组。.string
以返回实际匹配的文本。答案 1 :(得分:0)
实际上,发布的示例在Ruby中返回了#<MatchData "Happy">
,它也没有“全局”标志-这就是String#scan(Regex)
的用途,正如其他人所提到的。
如果您只想进行单次比赛而不经过Regex::MatchData
,则可以使用String#[](Regex)
:
str = "Happy days"
p str[/[a-z]+/i] # => "Happy"