String#gsub で選択子 | を使う時に注意したいこと

#sub #gsub する際に正規表現の選択子 (|) を使うことができるが、このチェックは正規表現ベースではなく、文字列ベースで 1 文字ずつイテレートしながら行われる*1
ので、意識せず | を使っていると思わぬところでハマりそう。

# "abc" を /a/ /ab/ /bc/ のパターンを使ってマッチさせたい場合

# /ab/ がなければ話は簡単
"abc".gsub(/bc|a/, "")
=> ""

# パターンとしては /bc/ が先にあるが、
# 文字列をベースにチェックしていくので"a" と/ab/ が先にマッチする
"abc".gsub(/bc|ab|a/, "")
# => "c"

# 先にマッチさせたいパターンを単独で先にマッチさせると期待通りの挙動となる
"abc".gsub(/bc/, "").gsub(/ab|a/, "")
# => ""

先読み & 後読みでなんとか書けそうな気はするけど、その辺はまだよくわからない…

*1:動作的にそうだったけどコードベースで確認したわけではないです