我正在使用 Ruby 3.2.1,我知道 Ruby 的正则表达式引擎已经发生了变化。这可能与此相关,也可能不相关。但是,在使用反向引用时,我从 String#match 和 String#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 不返回更多匹配项,甚至一个更长的匹配项?我假设这是我在捕获表达式中的错误,但我无法真正弄清楚我在这里做错了什么。
如果模式包含组,则每个结果都是一个数组,其中包含一个 每组条目。 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"]