質問: rubyの正規表現を扱う際の挙動についてよくわからないことがあります。 HTMLのパースをしているのですが、 ``` Regexp.new("スタックオーバーフロー") => /スタックオーバーフロー/ Regexp.new("スタックオーバーフロー") => /\u30B9\u30BF\u30C3\u30AF\u30AA\u30FC\u30D0\u30FC\u30D5\u30ED\u30FC<\/h1>/ ``` というような、上はUTF-8そのままで正規表現化できるのですが下の場合はunicodeがそのまま出てきてしまうという動きになっており、なぜこのようになるのかわかりません。 理想としては ``` => /スタックオーバーフロー<\/h1>/ ``` という正規表現がほしいのですが、どのようにすればよいでしょうか? あまり文字コードや文字セットなどに詳しくないので見当ハズレなことを聞いているのかもしれませんが、よろしくお願いします。
回答: ### 何がおきているか `ri Regexp#to_s` を見ると以下のように表示されます。 ``` = Regexp#to_s (from ruby core) rxp.to_s -> str Returns a string containing the regular expression and its options (using the (?opts:source) notation. This string can be fed back in to Regexp::new to a regular expression with the same semantics as the original. (However, Regexp#== may not return true when comparing the two, as the source of the regular expression itself may differ, as the example shows). Regexp#inspect produces a generally more readable version of rxp. r1 = /ab+c/ix #=> /ab+c/ix s1 = r1.to_s #=> "(?ix-m:ab+c)" r2 = Regexp.new(s1) #=> /(?ix-m:ab+c)/ r1 == r2 #=> false r1.source #=> "ab+c" r2.source #=> "(?ix-m:ab+c)" ``` 特に、 `Regexp#== may not return true when comparing the two` が重要だと考えていて、`to_s` メソッドによって返されるのは、 `Regexp.new` に引数として与えた時に、同じ文字列セットに一致するような正規表現を返すような文字列である、以外に期待してはいけないと考えられます。 ### 今回ほしかったもの おそらく、今回欲しいのは `Regexp#source` だと思います。 ``` regex = Regexp.new("スタックオーバーフロー") puts regex.source # => スタックオーバーフロー regex = Regexp.new("スタックオーバーフロー") puts regex.source # => スタックオーバーフロー ```