要旨
unicode(正確にはutf8)を前提に、全角か半角かわからない文字列を与えられている時にそれが確かにASCIIであると判別する正規表現を書けますか?
※タイトルが逆だったりと、何かとあれあったので整理しました。
結論
http://rubular.com/で色々試したところ
/\P{ascii}+/
あるいは /\p{ascii}+/
というシンプルな表記で(日本語以外含む)「マルチバイト文字列」と「ASCIIのみの文字列」を判別できるということを発見しました。1
/\P{ascii}+/
は
/[^_a-z\~\`\!\@\#\$\%\^\&\*\(\)\-\+\=\[\]\{\}\|\;\:\\'\"\,\.\<\>\/\?\/\d\s]+/i
に相当します。
もちろん"Ascii"などの全角英数もきちっと判別できます。
↑なんで\w
使わないの?って思うかもしれませんが、perlではuse utf8
支配下では**\w
はほとんどのマルチバイト文字にマッチしてしまうので使えません。**
ちなみにperl2以外は試してませんので、これが通る他の言語を教えてもらえたらタグ付けしますので編集リクエストお願いします。
なお、MacのUSキーボードなどで入力できる[˜ˆ]は、@scivolaさんのコメントによりマルチバイト文字と判明しました。3
背景(という以下蛇足)
全角半角入り混じるvCardデータを拙作のモジュールでText::LineFoldを駆使して、マルチバイト文字列ならスペース一個、非マルチバイト文字列(要するにasciiのみの文字列)ならスペース二個でFoldしないと正しいvCard形式にならないという問題を解決したかった。
モジュールの要旨からして日本語文字列を検出できれば良いというわけではなく、全世界的に対応させたかった。
おしい参考文献など
-
願望を入力したら通った… ↩
-
要perl-5.12.5以上 ↩
-
˜
は ASCII のチルダ(~ U+007E TILDE)ではなく U+02DC SMALL TILDE。二文字目のˆ
は ASCII のサーカムフレックス(^ U+005E CIRCUMFLEX ACCENT)ではなく U+02C6 MODIFIER LETTER CIRCUMFLEX ACCENT だそうです。 ↩ -
これはなるほどな、って記述ですが、そのまま使うとタブや改行にはマッチしてしまうようだ。
[^ -~\s]
ならOK ↩ -
言語依存のようだ ↩
-
ASCIIだけを抽出するコードとしては正しいが、
\p{ascii}
に関する言及がない ↩