全角スペースを正規表現でマッチさせたいけど、\s
だとマッチしない。これは \s
や \d
といった正規表現の文字クラスの略記法が ASCII の範囲の文字のみを対象 としているからなんです。
ひどいよ… こんなのってないよ…
じゃあ、半角スペースと全角スペースの両方にうまくマッチさせるにはどうしたらいいのでしょう。
それでは、「苗字と名前が半角もしくは全角のスペースで区切られた日本人の氏名の文字列から
正規表現を使って苗字と名前をそれぞれ取り出す」という例をもとに考えてみましょう。
方法1: 文字クラス内で全角スペースを指定する
"佐倉 杏子" =~ /^(.+?)[\s ]+(.+)$/
puts $1 #=> "佐倉"
puts $2 #=> "杏子"
文字クラス (角括弧) の中に \s
と " "
(全角スペース) を並べて指定します。でも正規表現に直接全角スペースを入力するのはなんだか嫌ですね。
方法2: Unicode プロパティの blank を利用する
Unicode プロパティ といふものありけり。\p{blank}
が全角スペース (ASCIIコード範囲外の空白) にもマッチします。
"佐倉 杏子" =~ /^(.+?)\p{blank}+(.+)$/
puts $1 #=> "佐倉"
puts $2 #=> "杏子"
方法3: POSIX 文字クラスの blank を利用する
POSIX 文字クラス といふものありけり。[[:blank:]]
が全角スペース (ASCIIコード範囲外の空白) にもマッチします。
"佐倉 杏子" =~ /^(.+?)[[:blank:]]+(.+)$/
puts $1 #=> "佐倉"
puts $2 #=> "杏子"
参考
全部 Ruby 2.3.0 リファレンスマニュアルの正規表現のページ に載っていました。Unicode プロパティも! POSIX 文字クラスも! (説明が) あるんだよ!Ruby のリファレンス素晴らしい (*´д`*) ハァハァ
正規表現小ネタ
# 全角スペースを2つ重ねた場合
# その1
"佐倉 杏子" =~ /^(.+)[[:blank:]]+(.+)$/
puts $1 #=> "佐倉 "
puts $2 #=> "杏子"
# その2
"佐倉 杏子" =~ /^(.+?)[[:blank:]]+(.+)$/
puts $1 #=> "佐倉"
puts $2 #=> "杏子"
全角スペースを2つ重ねた場合、苗字にマッチさせる部分で控えめな量指定子 +?
を使わないと
1つ目の全角スペースにまでマッチしてしまいます。正規表現の量指定子は欲張りなのだそうです。
この辺については 正規表現で最短マッチを知っとくとちょっと便利かも が非常に参考になりました。