Bug #18471


Regex#match(re, position) with start of a string anchors ^ and \A

Added by vlazar (Vlad Zarakovsky) 4 months ago. Updated 4 months ago.

Target version:


Found this. Is it a bug in Regex#match(re, position)?

From Regex#match docs

If the second parameter is present, it specifies the position in the string to begin the search.

str = "hello world"
/^world/.match(str, 6) # => nil
/\Aworld/.match(str, 6) # => nil

I would expect “specifies the position in the string to begin the search” would mean staring from position 6 in “hello world” should be equivalent to staring with position 0 in a string “world” and thus ^ or \A should match in this case too.

Consider another example. If I use the same with StringScanner#scan it works as I would expect:

require "strscan"

str = "hello world"
scanner =
scanner.pos = 6
scanner.scan /^world/ # => "world"
scanner.pos = 6
scanner.scan /\Aworld/ # => "world"

To me these 2 cases (at least looking into current API docs) should work the same and having a difference in behavior looks like a bug to me.

Updated by sawa (Tsuyoshi Sawada) 4 months ago

I [...] expect [...] staring from position 6 in “hello world” [to] be equivalent to staring with position 0 in [the sub-]string “world”

I do not think so. Moving "the position in the string to begin the search" does not mean the string will be truncated. It only moves the cursor position in the same string. It does not create a new string or a new edge of a string.

On the other hand, I find the behavior of StringScanner#scan to be potentially confusing, but I think I can understand why it is designed so. To my understanding, as you read from a StringScanner instance, the matched part is consumed, the original content is truncated, and indeed new edges are created as you read from it. And the same thing seems to be happening when the position is moved. (Saying somewhat metaphorically. I do not know about the actual implementation.)

Thus, I think String and StringScanner differ in nature. And particularly, String#match is not destructive whereas StringScanner#scan, StringScanner#pos= are destructive.

Updated by znz (Kazuhiro NISHIYAMA) 4 months ago

\G matches.

str = "hello world"
/\Gworld/.match(str, 6)
Actions #3

Updated by jeremyevans0 (Jeremy Evans) 4 months ago

  • Status changed from Open to Rejected

Also available in: Atom PDF