PHP - 仅限ASCII扩展字符的字符串

时间:2014-06-17 16:11:05

标签: php regex

使用PHP我想知道我的$ string是否包含此列表中33到255之间的任何非ASCII扩展字符:http://www.ascii-code.com/

此外,是否可以包含其他各种ASCII字符以拒绝?像182和135(相应的¶和‡符号)。我的意思是,如果$ string有这个,我想得到一个bool也是假的。

我知道如何使用ASCII,但不能使用ASCII扩展。

3 个答案:

答案 0 :(得分:3)

扩展ASCII为十进制128-255,普通(7位)ASCII可打印字符为32(空格)到126(波浪号)。

因此,找到正常可打印范围之外的任何8位字符的正则表达式将是:

/[^ -~]/

基本上,这表示“不是通过代字号”。在PHP中:

$nonprintable_or_extended = preg_match('/[^ -~]/', $string) === 1;

编辑添加: 我重新阅读了你的问题,第二个想法我认为你也想要允许一些“扩展ASCII”字符。对此没有简单的答案,因为代码点127之上的任何内容都涉及字符编码。在美国,我们通常使用以下3种中的一种:

  1. ISO-8859-1定义了Latin-1并允许e-grave,e-acute等。 字符在128-255范围内,有一些空白 (http://en.wikipedia.org/wiki/Iso_8859-1)。
  2. cp1252(或Windows 代码页1252)基本上是ISO-8859-1,除了它增加了更多 129-159范围内的字符,ISO-8859-1未分配 (http://en.wikipedia.org/wiki/Cp1252)。
  3. UTF-(8,16,32)字符串使用集合 高阶ASCII字符,用于解决整个代码点 Unicode频谱(65535及以上),因此搞清楚“什么是 这里有效的可打印字符?“需要更多的思考。
  4. 根据以下评论进行编辑:如果您想允许某些字符,请先对输入编码进行标准化。我们将以UTF-8运行,我们可以检查并转换cp1252 / ISO-8859-1的编码:

    // Validate the UTF-8 (from drupal_validate_utf8()).
    // @see https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_validate_utf8/7
    if (strlen($string) != 0 && preg_match('/^./us', $string) !== 1) {
      // Convert to UTF-8 if it isn't already (assuming input was "Western" cp1252/ISO).
      $string = @iconv('Windows-1252', 'UTF-8//IGNORE', $string);
    }
    

    现在$string保证是有效的UTF-8编码字符串。然后,只允许单字节“扩展ASCII”(拉丁文-1和cp1252提供的补充),并以区域设置感知方式音译类似字符:

    // Ensure the locale is right for our iconv() operations.
    // This establishes how transliteration will determine the appropriate destination character(s).
    setlocale(LC_CTYPE, 'en_US.UTF-8');
    $string = iconv('utf-8', 'CP1252//TRANSLIT//IGNORE', $string);
    

    此时$string将是一个cp1252,单字节表示字符串;超出该范围的任何内容将被音译(如果可能)或丢弃。您可以在此处使用REGEX进行进一步过滤,例如:

    // 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);
    

答案 1 :(得分:1)

编辑:请参阅此working demo

来自!到ÿ

要检查在ASCII范围内是否有的任何字符,33至255非常容易。只需使用此正则表达式:

`[^!-ÿ]`

这是一个否定的字符类,匹配!ÿ之间的任何字符。请注意,扩展的ASCII范围取决于计算机的区域设置。它应该适合你。

同时排除

为了排除这些字符,我们可以将初始的否定类分解为三个范围,以便在两个新字符周围留出空间:从!ˆ之前的字符...来自角色ˆ之后的字符之后...从之后的字符转移到ÿ

但是将两个字符添加到自己的类中并使用 OR 加入它们会更清晰(也更易于维护)。你可以使用这个正则表达式:

`[ˆ¶]|[^!-ÿ]`
  • 如果找到[ˆ¶]中的两个字符之一,或者|
  • ,我们会匹配
  • 如果角色不在!-ÿ范围内。

要添加排除项,只需在第一个类中添加字符。

答案 2 :(得分:0)

用于检测扩展的ASCII字符集使用:

$extended = preg_match('/[\x7f-\xff]/', $str );