扩展ASCII码在十进制128-255之间,而普通(7位)ASCII可打印字符为32(空格)至126(波浪号)。
因此,用于查找任何超出正常可打印范围的8位字符的正则表达式将是:
/[^ -~]/
基本上,这意味着“不包括空格到波浪号”。在PHP中:
$nonprintable_or_extended = preg_match('/[^ -~]/', $string) === 1
编辑后添加:
我重新阅读了你的问题,并且经过思考,我认为你也希望允许一些“扩展ASCII”字符。对于这个问题没有简单的答案,因为任何超过代码点127的字符都涉及到字符编码。在美国,我们通常使用以下三种之一:
- ISO-8859-1定义了Latin-1字符集,并允许在128-255范围内使用e-grave、e-acute等字符,但有一些空缺(http://en.wikipedia.org/wiki/Iso_8859-1)。
- cp1252(或Windows Codepage 1252)基本上与ISO-8859-1相同,只是它在129-159范围内添加了更多的字符,而ISO-8859-1则保留了这些未分配的字符(http://en.wikipedia.org/wiki/Cp1252)。
- UTF-(8, 16, 32)字符串使用高阶ASCII字符集来寻址整个Unicode光谱(65535及以上),因此要想知道“什么是有效的可打印字符?”,需要更多的思考。
根据下面的评论进行编辑:如果您想允许某些字符,请先标准化输入编码。我们将使用UTF-8进行操作,可以检查和转换cp1252/ISO-8859-1的编码:
if (strlen($string) != 0 && preg_match('/^./us', $string) !== 1) {
$string = @iconv('Windows-1252', 'UTF-8//IGNORE', $string);
}
现在
$string
已经保证是一个有效的UTF-8编码字符串。然后,为了只允许单字节的“扩展ASCII”(Latin-1和cp1252提供的补充),并以区域设置感知的方式转换类似的字符:
setlocale(LC_CTYPE, 'en_US.UTF-8');
$string = iconv('utf-8', 'CP1252//TRANSLIT//IGNORE', $string);
在这一点上,
$string
将是一个cp1252的单字节表示字符串;任何超出该范围的内容都将被转换(如果可能)或丢弃。您可以使用正则表达式进一步进行过滤,例如:
// Allow only printable characters (exclude control codes below \x20 [space char]),
// and only the Euro cp1252 character (\x80) and A-tilde (Ãã) characters (\xC3 and \xE3).
$filtered_string = preg_replace('[\x20-\x7F\x80\xC3\xE3]+', '', $string);
48
代表数字0
,为什么它被称为非ASCII扩展字符? - anubhava