UTF-8の正規表現

弾さんのところにUTF-8 vs. ISO-10646というentryが。PerlではルーズなUTF-8のことをutf8と読んでましたね。
というわけで、UTF-8 の文字にマッチする正規表現という話。蛇足になりますけれど、もっと厳密にしますと、最短でないUTF-8表現を除外できるので、

$RE_UTF8CHAR_STRICT_AND_SECURE
 = qr/(?:
    [\x00-\x7F] |			# U+0000 - U+007F
    [\xC2-\xDF][\x80-\xBF] |		# U+0080 - U+07FF
    \xE0[\xA0-\xBF][\x80-\xBF] |	# U+0800 - U+0FFF
    [\xE1-\xEC][\x80-\xBF]{2} |		# U+1000 - U+CFFF
    \xED[\x80-\x9F][\x80-\xBF] |	# U+D000 - U+D7FF
    \xEF[\x80-\xBF][\x80-\xBF] |	# U+E000 - U+FFFF
    \xF0[\x90-\xBF][\x80-\xBF]{2} |	# U+10000 - U+3FFFF
    [\xF1-\xF3][\x80-\xBF]{3} |		# U+40000 - U+FFFFF
    \xF4[\x80-\x8F][\x80-\xBF]{2}	# U+100000 - U+10FFFF
 )/x;

ともできたり。ここからさらにU+FFFEやU+FFFFが無い、というのも考慮するとうれしい日もあるかもしれません。いや、無いかな。
まぁ、ここまでやってもしょうがないので、$RE_UTF8CHARを2文字だけ変えたものを。こちらの方が少し範囲が狭くなっています。

$RE_UTF8CHAR_MORE_STRICT
 = qr/(?:[\x00-\x7f]|[\xC2-\xDF][\x80-\xBF]|
      [\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF4][\x80-\xBF]{3})/x;

こちらの方が多くの場合実用的でしょう。