为什么#match返回正确的结果,而#scan只找到一个字母?

问题描述 投票:0回答:1

问题背景

我正在使用 Ruby 3.2.1,我知道 Ruby 的正则表达式引擎已经发生了变化。这可能与此相关,也可能不相关。但是,在使用反向引用时,我从 String#matchString#scan 得到了意想不到的不同行为,我不明白为什么。请参阅下面的示例代码。

我的例子,评论和期望

比赛结果
# Using #match finds the longest string of
# repeated letters, and the letter that is
# repeated.
"gjhfgfcttttdfs".match /(\p{alpha})\1{2,}/
=> #<MatchData "tttt" 1:"t">
扫描无法正常工作,出现意外结果
# Here, #scan returns only a single sub-
# array with a single letter, which is
# the correct letter. However, I was
# expecting an array-of-arrays with all
# repeated letters.
"gjhfgfcttttdfs".scan /(\p{alpha})\1{2,}/
=> [["t"]]

澄清问题

假设键盘和椅子之间存在问题,为什么 String#scan 不返回更多匹配项,甚至一个更长的匹配项?我假设这是我在捕获表达式中的错误,但我无法真正弄清楚我在这里做错了什么。

regex ruby string backreference
1个回答
1
投票

如果模式包含组,则每个结果都是一个数组,其中包含一个 每组条目。 https://rubyapi.org/3.2/o/string#method-i-scan

似乎有点模糊,但我认为已经这样了很长时间。

>> "aaabccc".match /(\p{alpha})\1{2,}/
=> #<MatchData "aaa" 1:"a">
>> "aaabccc".scan /(\p{alpha})\1{2,}/
=> [["a"], ["c"]]

要获得整场比赛,你可以捕捉它,成为

scan
结果的一部分:

>> "aaabccc".match /((\p{alpha})\2{2,})/
=> #<MatchData "aaa" 1:"aaa" 2:"a">
#                    ^       ^
# two captures will return two captured results for each match
>> "aaabccc".scan /((\p{alpha})\2{2,})/
=> [["aaa", "a"], ["ccc", "c"]]

# that's the best i could come up with this
>> "aaabccc".scan(/((\p{alpha})\2{2,})/).map(&:first)
=> ["aaa", "ccc"]

完全匹配只能从

scan
块获得:

>> a = []; "aaabccc".scan(/(\p{alpha})\1{2,}/) { a << $& }; a
=> ["aaa", "ccc"]
© www.soinside.com 2019 - 2024. All rights reserved.