天道酬勤,学无止境

适用于UTF-8的多字节安全wordwrap()函数(Multi-byte safe wordwrap() function for UTF-8)

问题

PHP的wordwrap()函数不适用于UTF-8等多字节字符串。

注释中有几个mb安全功能示例,但是使用一些不同的测试数据,它们似乎都存在一些问题。

该函数应采用与wordwrap()完全相同的参数。

特别要确保它能:

  • 如果$cut = true则切中单词,否则不切中单词
  • 如果$break = ' '则不能在单词中插入多余的空格
  • 也适用于$break = "\n"
  • 适用于ASCII和所有有效的UTF-8
回答1

我还没有找到适合我的工作代码。 这是我写的。 对我来说,它正在运行,以为它可能不是最快的。

function mb_wordwrap($str, $width = 75, $break = "\n", $cut = false) {
    $lines = explode($break, $str);
    foreach ($lines as &$line) {
        $line = rtrim($line);
        if (mb_strlen($line) <= $width)
            continue;
        $words = explode(' ', $line);
        $line = '';
        $actual = '';
        foreach ($words as $word) {
            if (mb_strlen($actual.$word) <= $width)
                $actual .= $word.' ';
            else {
                if ($actual != '')
                    $line .= rtrim($actual).$break;
                $actual = $word;
                if ($cut) {
                    while (mb_strlen($actual) > $width) {
                        $line .= mb_substr($actual, 0, $width).$break;
                        $actual = mb_substr($actual, $width);
                    }
                }
                $actual .= ' ';
            }
        }
        $line .= trim($actual);
    }
    return implode($break, $lines);
}
回答2
/**
 * wordwrap for utf8 encoded strings
 *
 * @param string $str
 * @param integer $len
 * @param string $what
 * @return string
 * @author Milian Wolff <mail@milianw.de>
 */

function utf8_wordwrap($str, $width, $break, $cut = false) {
    if (!$cut) {
        $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.',}\b#U';
    } else {
        $regexp = '#^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){'.$width.'}#';
    }
    if (function_exists('mb_strlen')) {
        $str_len = mb_strlen($str,'UTF-8');
    } else {
        $str_len = preg_match_all('/[\x00-\x7F\xC0-\xFD]/', $str, $var_empty);
    }
    $while_what = ceil($str_len / $width);
    $i = 1;
    $return = '';
    while ($i < $while_what) {
        preg_match($regexp, $str,$matches);
        $string = $matches[0];
        $return .= $string.$break;
        $str = substr($str, strlen($string));
        $i++;
    }
    return $return.$str;
}

总时间:0.0020880699是个好时间:)

回答3

因为没有答案在处理每个用例,所以可以做到这一点。 该代码基于Drupal的AbstractStringWrapper :: wordWrap。

<?php

/**
 * Wraps any string to a given number of characters.
 *
 * This implementation is multi-byte aware and relies on {@link
 * http://www.php.net/manual/en/book.mbstring.php PHP's multibyte
 * string extension}.
 *
 * @see wordwrap()
 * @link https://api.drupal.org/api/drupal/core%21vendor%21zendframework%21zend-stdlib%21Zend%21Stdlib%21StringWrapper%21AbstractStringWrapper.php/function/AbstractStringWrapper%3A%3AwordWrap/8
 * @param string $string
 *   The input string.
 * @param int $width [optional]
 *   The number of characters at which <var>$string</var> will be
 *   wrapped. Defaults to <code>75</code>.
 * @param string $break [optional]
 *   The line is broken using the optional break parameter. Defaults
 *   to <code>"\n"</code>.
 * @param boolean $cut [optional]
 *   If the <var>$cut</var> is set to <code>TRUE</code>, the string is
 *   always wrapped at or before the specified <var>$width</var>. So if
 *   you have a word that is larger than the given <var>$width</var>, it
 *   is broken apart. Defaults to <code>FALSE</code>.
 * @return string
 *   Returns the given <var>$string</var> wrapped at the specified
 *   <var>$width</var>.
 */
function mb_wordwrap($string, $width = 75, $break = "\n", $cut = false) {
  $string = (string) $string;
  if ($string === '') {
    return '';
  }

  $break = (string) $break;
  if ($break === '') {
    trigger_error('Break string cannot be empty', E_USER_ERROR);
  }

  $width = (int) $width;
  if ($width === 0 && $cut) {
    trigger_error('Cannot force cut when width is zero', E_USER_ERROR);
  }

  if (strlen($string) === mb_strlen($string)) {
    return wordwrap($string, $width, $break, $cut);
  }

  $stringWidth = mb_strlen($string);
  $breakWidth = mb_strlen($break);

  $result = '';
  $lastStart = $lastSpace = 0;

  for ($current = 0; $current < $stringWidth; $current++) {
    $char = mb_substr($string, $current, 1);

    $possibleBreak = $char;
    if ($breakWidth !== 1) {
      $possibleBreak = mb_substr($string, $current, $breakWidth);
    }

    if ($possibleBreak === $break) {
      $result .= mb_substr($string, $lastStart, $current - $lastStart + $breakWidth);
      $current += $breakWidth - 1;
      $lastStart = $lastSpace = $current + 1;
      continue;
    }

    if ($char === ' ') {
      if ($current - $lastStart >= $width) {
        $result .= mb_substr($string, $lastStart, $current - $lastStart) . $break;
        $lastStart = $current + 1;
      }

      $lastSpace = $current;
      continue;
    }

    if ($current - $lastStart >= $width && $cut && $lastStart >= $lastSpace) {
      $result .= mb_substr($string, $lastStart, $current - $lastStart) . $break;
      $lastStart = $lastSpace = $current;
      continue;
    }

    if ($current - $lastStart >= $width && $lastStart < $lastSpace) {
      $result .= mb_substr($string, $lastStart, $lastSpace - $lastStart) . $break;
      $lastStart = $lastSpace = $lastSpace + 1;
      continue;
    }
  }

  if ($lastStart !== $current) {
    $result .= mb_substr($string, $lastStart, $current - $lastStart);
  }

  return $result;
}

?>
回答4

自定义单词边界

Unicode文本比8位编码具有更多的潜在单词边界,包括17个空格和全角逗号。 该解决方案使您可以为应用程序自定义单词边界列表。

更好的性能

您是否曾经对mb_*系列的PHP内置程序进行过基准测试? 它们根本无法很好地扩展。 通过使用自定义的nextCharUtf8() ,我们可以完成相同的工作,但速度要快nextCharUtf8()数量级,尤其是在大型字符串上。

<?php

function wordWrapUtf8(
  string $phrase,
  int $width = 75,
  string $break = "\n",
  bool $cut = false,
  array $seps = [' ', "\n", "\t", ',']
): string
{
  $chunks = [];
  $chunk = '';
  $len = 0;
  $pointer = 0;
  while (!is_null($char = nextCharUtf8($phrase, $pointer))) {
    $chunk .= $char;
    $len++;
    if (in_array($char, $seps, true) || ($cut && $len === $width)) {
      $chunks[] = [$len, $chunk];
      $len = 0;
      $chunk = '';
    }
  }
  if ($chunk) {
    $chunks[] = [$len, $chunk];
  }
  $line = '';
  $lines = [];
  $lineLen = 0;
  foreach ($chunks as [$len, $chunk]) {
    if ($lineLen + $len > $width) {
      if ($line) {
        $lines[] = $line;
        $lineLen = 0;
        $line = '';
      }
    }
    $line .= $chunk;
    $lineLen += $len;
  }
  if ($line) {
    $lines[] = $line;
  }
  return implode($break, $lines);
}

function nextCharUtf8(&$string, &$pointer)
{
  // EOF
  if (!isset($string[$pointer])) {
    return null;
  }

  // Get the byte value at the pointer
  $char = ord($string[$pointer]);

  // ASCII
  if ($char < 128) {
    return $string[$pointer++];
  }

  // UTF-8
  if ($char < 224) {
    $bytes = 2;
  } elseif ($char < 240) {
    $bytes = 3;
  } elseif ($char < 248) {
    $bytes = 4;
  } elseif ($char == 252) {
    $bytes = 5;
  } else {
    $bytes = 6;
  }

  // Get full multibyte char
  $str = substr($string, $pointer, $bytes);

  // Increment pointer according to length of char
  $pointer += $bytes;

  // Return mb char
  return $str;
}
回答5

只想分享一些我在网上找到的选择。

<?php
if ( !function_exists('mb_str_split') ) {
    function mb_str_split($string, $split_length = 1)
    {
        mb_internal_encoding('UTF-8'); 
        mb_regex_encoding('UTF-8');  

        $split_length = ($split_length <= 0) ? 1 : $split_length;

        $mb_strlen = mb_strlen($string, 'utf-8');

        $array = array();

        for($i = 0; $i < $mb_strlen; $i += $split_length) {
            $array[] = mb_substr($string, $i, $split_length);
        }

        return $array;
    }
}

使用mb_str_split ,可以使用join将单词与<br>组合在一起。

<?php
    $text = '<utf-8 content>';

    echo join('<br>', mb_str_split($text, 20));

最后创建自己的帮助程序,也许是mb_textwrap

<?php

if( !function_exists('mb_textwrap') ) {
    function mb_textwrap($text, $length = 20, $concat = '<br>') 
    {
        return join($concat, mb_str_split($text, $length));
    }
}

$text = '<utf-8 content>';
// so simply call
echo mb_textwrap($text);

查看屏幕截图演示:

回答6
function mb_wordwrap($str, $width = 74, $break = "\r\n", $cut = false)
        {
            return preg_replace(
                '~(?P<str>.{' . $width . ',}?' . ($cut ? '(?(?!.+\s+)\s*|\s+)' : '\s+') . ')(?=\S+)~mus',
                '$1' . $break,
                $str
            );
        }
回答7

这是我从互联网上发现的其他代码中汲取灵感的多字节自动换行功能。

function mb_wordwrap($long_str, $width = 75, $break = "\n", $cut = false) {
    $long_str = html_entity_decode($long_str, ENT_COMPAT, 'UTF-8');
    $width -= mb_strlen($break);
    if ($cut) {
        $short_str = mb_substr($long_str, 0, $width);
        $short_str = trim($short_str);
    }
    else {
        $short_str = preg_replace('/^(.{1,'.$width.'})(?:\s.*|$)/', '$1', $long_str);
        if (mb_strlen($short_str) > $width) {
            $short_str = mb_substr($short_str, 0, $width);
        }
    }
    if (mb_strlen($long_str) != mb_strlen($short_str)) {
        $short_str .= $break;
    }
    return $short_str;
}

不要忘记将PHP配置为使用UTF-8:

ini_set('default_charset', 'UTF-8');
mb_internal_encoding('UTF-8');
mb_regex_encoding('UTF-8');

我希望这将有所帮助。 纪尧姆

回答8

这是我自己对通过了一些测试的函数的尝试,尽管我不能保证它是100%完美的,所以如果发现问题,请发布更好的函数。

/**
 * Multi-byte safe version of wordwrap()
 * Seems to me like wordwrap() is only broken on UTF-8 strings when $cut = true
 * @return string
 */
function wrap($str, $len = 75, $break = " ", $cut = true) { 
    $len = (int) $len;

    if (empty($str))
        return ""; 

    $pattern = "";

    if ($cut)
        $pattern = '/([^'.preg_quote($break).']{'.$len.'})/u'; 
    else
        return wordwrap($str, $len, $break);

    return preg_replace($pattern, "\${1}".$break, $str); 
}
回答9

这个似乎运作良好...

function mb_wordwrap($str, $width = 75, $break = "\n", $cut = false, $charset = null) {
    if ($charset === null) $charset = mb_internal_encoding();

    $pieces = explode($break, $str);
    $result = array();
    foreach ($pieces as $piece) {
      $current = $piece;
      while ($cut && mb_strlen($current) > $width) {
        $result[] = mb_substr($current, 0, $width, $charset);
        $current = mb_substr($current, $width, 2048, $charset);
      }
      $result[] = $current;
    }
    return implode($break, $result);
}

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Multi-byte safe wordwrap() function for UTF-8
    PHP's wordwrap() function doesn't work correctly for multi-byte strings like UTF-8. There are a few examples of mb safe functions in the comments, but with some different test data they all seem to have some problems. The function should take the exact same parameters as wordwrap(). Specifically be sure it works to: cut mid-word if $cut = true, don't cut mid-word otherwise not insert extra spaces in words if $break = ' ' also work for $break = "\n" work for ASCII, and all valid UTF-8
  • 如何截断PHP中最接近一定数量字符的单词的字符串?(How to Truncate a string in PHP to the word closest to a certain number of characters?)
    问题 我有一个用PHP编写的代码片段,可从数据库中提取文本块并将其发送到网页上的小部件。 原始文本块可以是一篇冗长的文章或一两个简短的句子; 但是对于此小部件,我最多只能显示200个字符。 我可以使用substr()以200个字符的形式截断文本,但是结果是在中间截断-我真正想要的是在200个字符之前的最后一个的末尾截断文本。 回答1 通过使用自动换行功能。 它将文本分成多行,以使最大宽度是您指定的宽度,并在单词边界处断开。 拆分后,您只需走第一行: substr($string, 0, strpos(wordwrap($string, $your_desired_width), "\n")); 文本本身短于所需宽度时,oneliner无法处理的一件事。 要处理这种情况,应执行以下操作: if (strlen($string) > $your_desired_width) { $string = wordwrap($string, $your_desired_width); $string = substr($string, 0, strpos($string, "\n")); } 如果文本在实际剪切点之前包含换行符,则上述解决方案存在过早剪切文本的问题。 这里是解决此问题的版本: function tokenTruncate($string, $your_desired_width
  • PHP preg_functions多字节安全吗?(Are the PHP preg_functions multibyte safe?)
    问题 PHP没有可用的多字节“ preg”函数,这是否意味着默认的preg_functions都是mb安全的? 在php文档中找不到任何提及。 回答1 PCRE可以支持UTF-8和其他Unicode编码,但是必须在编译时指定。 从PCRE 8.0的手册页中: PCRE的当前实现大致与Perl 5.10相对应,包括对UTF-8编码的字符串和Unicode常规类别属性的支持。 但是,必须明确启用UTF-8和Unicode支持。 它不是默认值。 Unicode表对应于Unicode版本5.1。 PHP当前使用PCRE 7.9; 您的系统可能具有较旧的版本。 看一下PHP 5.2附带的PCRE库,似乎它已配置为支持Unicode属性和UTF-8。 与5.3分支相同。 回答2 pcre开箱即用地支持utf8,请参见'u'修饰符的文档。 插图(\ xC3 \ xA4是德语字母“ä”的utf8编码) echo preg_replace('~\w~', '@', "a\xC3\xA4b"); 这回显“ @@¤@”,因为“ \ xC3”和“ \ xA4”被视为不同的符号 echo preg_replace('~\w~u', '@', "a\xC3\xA4b"); (请注意'u')打印“ @@@”,因为“ \ xC3 \ xA4”被视为单个字母。 回答3 不,他们不是。 例如
  • PHP中的多字节修饰?(Multibyte trim in PHP?)
    问题 显然mb_ *系列中没有mb_trim ,因此我正在尝试为自己实现一个。 我最近在php.net的评论中找到了此正则表达式: /(^\s+)|(\s+$)/u 因此,我将通过以下方式实现它: function multibyte_trim($str) { if (!function_exists("mb_trim") || !extension_loaded("mbstring")) { return preg_replace("/(^\s+)|(\s+$)/u", "", $str); } else { return mb_trim($str); } } 正则表达式对我来说似乎是正确的,但是我对正则表达式非常陌生。 这样可以有效地删除字符串开头/结尾的任何Unicode空间吗? 回答1 标准trim功能可修剪少量空格和类似空格的字符。 这些被定义为ASCII字符,表示从0到0100 0000某些特定字节。 正确的UTF-8输入永远不会包含由字节0xxx xxxx组成的多字节字符。 正确的UTF-8多字节字符中的所有字节1xxx xxxx开头。 这意味着在正确的UTF-8序列中,字节0xxx xxxx只能引用单字节字符。 因此,假设您具有正确的UTF-8序列,PHP的trim函数将永远不会修剪掉“一半字符”。 (对于不正确的UTF-8序列,要非常小心。)
  • UTF-8和ISO-8859-1有什么区别?
    本文翻译自:What is the difference between UTF-8 and ISO-8859-1? UTF-8和ISO-8859-1有什么区别? #1楼 参考:https://stackoom.com/question/TZhR/UTF-和ISO-有什么区别 #2楼 ISO-8859-1 is a legacy standards from back in 1980s. ISO-8859-1是20世纪80年代的传统标准。 It can only represent 256 characters so only suitable for some languages in western world. 它只能代表256个字符,因此只适用于西方世界的某些语言。 Even for many supported languages, some characters are missing. 即使对于许多支持的语言,也缺少一些字符。 If you create a text file in this encoding and try copy/paste some Chinese characters, you will see weird results. 如果您使用此编码创建文本文件并尝试复制/粘贴一些中文字符,您将看到奇怪的结果。 So in other words
  • 如何在Visual Studio Code中打开和关闭自动换行?(How can I switch word wrap on and off in Visual Studio Code?)
    问题 使用代码文件时,通常不需要较长的行来回绕。 但是,对于.md文件,这实际上非常有用。 但是,我似乎找不到启用自动换行的选项,因此将换行更长的行。 要进行复制,请打开将Visual Studio Code调整为一个足够小的窗口,然后在新文档中输入以下文本: This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. This is my test lorem ipsum. A linebreak before this. 效果是这样的: 我正在尝试使水平滚动条保持不动,在窗口的右侧缠绕第1行。 我做了一些事情来回答我自己的问题: 搜索堆栈溢出:撰写本文时,结果为零; 仔细浏览Visual Studio Code菜单:找不到它;没有找到它。 将命令选项板与“ wrap”一起使用:不提供匹配的命令。 也许这是不可能的,而我需要提出功能请求? 还是我错过了什么? 请注意
  • 最佳自动换行算法? [关闭](Best word wrap algorithm? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 1年前关闭。 改善这个问题 自动换行是现代文本编辑器中的必备功能之一。 如何处理自动换行? 换行的最佳算法是什么? 如果文本是几百万行,那么我该如何快速自动换行呢? 为什么需要解决方案? 因为我的项目必须绘制具有各种缩放级别并同时具有美观外观的文本。 运行环境是Windows Mobile设备。 很小的内存大小,最高600 MHz速度。 我应该如何处理线路信息? 假设原始数据有三行。 THIS IS LINE 1. THIS IS LINE 2. THIS IS LINE 3. 之后,中断文本将如下所示: THIS IS LINE 1. THIS IS LINE 2. THIS IS LINE 3. 我应该再分配三行吗? 或其他建议? 回答1 这是我用C#编写的自动换行算法。 翻译成其他语言应该很容易(也许IndexOfAny除外)。 static char[] splitChars = new char[] { ' ', '-', '\t' }; private static string WordWrap(string str, int width) { string[] words = Explode(str, splitChars)
  • 如何在PHP中迭代UTF-8字符串?(How to iterate UTF-8 string in PHP?)
    问题 如何使用索引逐个字符地迭代UTF-8字符串? 使用方括号运算符$str[0]访问UTF-8字符串时,utf编码的字符包含2个或更多元素。 例如: $str = "Kąt"; $str[0] = "K"; $str[1] = "�"; $str[2] = "�"; $str[3] = "t"; 但我想拥有: $str[0] = "K"; $str[1] = "ą"; $str[2] = "t"; mb_substr是可能的,但这非常慢,即。 mb_substr($str, 0, 1) = "K" mb_substr($str, 1, 1) = "ą" mb_substr($str, 2, 1) = "t" 还有另一种方法可以不使用mb_substr逐字符插入字符串吗? 回答1 使用preg_split。 使用“ u”修饰符,它支持UTF-8 Unicode。 $chrArray = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY); 回答2 Preg拆分将在内存异常的情况下对非常大的字符串进行故障转移,并且mb_substr确实很慢,因此这是一个简单而有效的代码,我敢肯定,您可以使用: function nextchar($string, &$pointer){ if(!isset($string[$pointer]))
  • 在CSS / JS中自动换行(word wrap in css / js)
    问题 我正在寻找一种跨浏览器的方式来包装具有预定宽度的div内不包含空格(例如长URL)的文本的较长部分。 这里有一些解决方案,我在网络上找到,为什么他们不为我工作: 溢出:隐藏/自动/滚动-我需要整个文本在不滚动的情况下可见。 div可以垂直增长,但不能水平增长。 注射&shy; 通过js /服务器端输入字符串-&shy; FF3现在支持FF3,但是复制和粘贴带有&shy;的URL。 在中间无法在Safari中使用。 另外,据我所知,没有一种干净的方法来测量文本宽度,以找出最佳的字符串偏移量以将这些字符添加到其中(这是一种怪癖,请参阅下一项)。 另一个问题是,放大Firefox和Opera可以轻松解决这个问题。 将文本转储到隐藏元素中并测量offsetWidth-与上面的项目有关,它需要在字符串中添加额外的字符。 同样,测量一长段文本所需的中断数量可能很容易需要数千个昂贵的DOM插入(每个子字符串长度一个),这可以有效地冻结该站点。 使用等宽字体-再次,缩放会弄乱宽度计算,并且文本无法随意设置样式。 看起来很有希望但还不存在的事情 word-wrap:断行词-它现在是CSS3工作草案的一部分,但Firefox,Opera或Safari尚不支持。 如果它今天可以在所有浏览器中使用,那么这将是理想的解决方案:( 通过js /服务器端将<wbr>标记注入字符串中
  • 如何在不打断单词的情况下拆分长字符串?(How to split a long string without breaking words?)
    问题 我正在寻找一些类似的东西 str_split_whole_word($longString, $x) 其中$longString是句子的集合,而$x是每行的字符长度。 它可能会很长,我想将其基本上以数组的形式分成多行。 例如: $longString = 'I like apple. You like oranges. We like fruit. I like meat, also.'; $lines = str_split_whole_word($longString, $x); 所需的输出: $lines = Array( [0] = 'I like apple. You' [1] = 'like oranges. We' [2] = and so on... ) 回答1 这段代码可以避免打断​​单词,您不会使用wordwrap()来获得它。 最大长度使用$maxLineLength定义。 我已经做过一些测试,并且工作正常。 $longString = 'I like apple. You like oranges. We like fruit. I like meat, also.'; $words = explode(' ', $longString); $maxLineLength = 18; $currentLength = 0; $index = 0
  • 限制字符串长度(Limit String Length)
    问题 我正在寻找一种方法来限制php中的字符串,并在字符串过长时在末尾添加...。 回答1 您可以使用类似于以下内容的东西: if (strlen($str) > 10) $str = substr($str, 0, 7) . '...'; 回答2 从PHP 4.0.6开始,有一个功能完全相同 函数mb _ strimwidth可以用于您的需求 <?php echo mb_strimwidth("Hello World", 0, 10, "..."); //Hello W... ?> 它确实有更多选项,这是此mb_strimwidth的文档 回答3 如果不想拆分单词,可以使用wordwrap()函数然后在换行符上爆炸并开始第一部分。 $str = 'Stack Overflow is as frictionless and painless to use as we could make it.'; $str = wordwrap($str, 28); $str = explode("\n", $str); $str = $str[0] . '...'; 资料来源:https://stackoverflow.com/a/1104329/1060423 如果您不关心拆分单词,则只需使用php substr函数。 echo substr($str, 0, 28) . '...'
  • UTF-8安全等效于PHP中的ord或charCodeAt()(UTF-8 safe equivalent of ord or charCodeAt() in PHP)
    问题 我需要能够使用ord()获得与javascript的charCodeAt()函数相同的值。 问题在于ord()不支持UTF8。 如何在PHP中将Ą转换为260? 我已经尝试了一些uniord函数,但是它们都报告了256个而不是260个。 非常感谢您的帮助! 问候 回答1 ord()每字节工作一个字节(与大多数PHP标准字符串函数相同-如果不是全部)。 您将需要自己进行转换,例如借助多字节字符串扩展名: $utf8Character = 'Ą'; list(, $ord) = unpack('N', mb_convert_encoding($utf8Character, 'UCS-4BE', 'UTF-8')); echo $ord; # 260 回答2 mbstring版本: function utf8_char_code_at($str, $index) { $char = mb_substr($str, $index, 1, 'UTF-8'); if (mb_check_encoding($char, 'UTF-8')) { $ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8'); return hexdec(bin2hex($ret)); } else { return null; } }
  • Linux Unicode 编程--C语言如何使用/生成UTF-8编码格式的文件
    Unicode并不只是一个编程工具,它还是一个政治的、经济的工具。没有结合世界的语言支持的应用程序通常只能被那些能读写ASCII所支持语言的个人使用。这使得建立在ASCII基础之上的计算机技术脱离了世界上大部分人。Unicode允许程序使用世界上任何一种字符集,因此它支持所有语言。Unicode让程序员为普通人提供用他们本国语言就能使用的软件。这样就不用再学一门外语了,而且更容易实现计算机技术社会和财政上的利益。很容易设想,如果用户必须为使用因特网浏览器而学习乌尔都语的话,您就难以看到计算机在美国的使用。Web就更不会出现了。Linux承担了对Unicode很大程度上的支持。Unicode支持被嵌入到内核和代码开发库中。在很大程度上,使用程序中几句简单的命令就能将它们自动的结合到代码中。所有现代字符集的基础都是在1968年以ANSIX3.4版本出版的美国信息交换标准码(AmericanStandardCodeforInformationInterchange,ASCII)。一个值得注意的例外是在ASCII之前定义的IBM的扩充的二进制编码的十进制交换码(ExtendedBinaryCodedDecimalInformationCode,EBCDIC)。ASCII是一个编码字符集(codedcharacterset,CCS),换句话说,它是整数到字符表示的映射
  • 无法在mongodb中创建索引,“键太大而无法索引”(Cannot create index in mongodb, “key too large to index”)
    问题 我在mongodb中创建索引,该索引有1000万条记录,但是出现以下错误 db.logcollection.ensureIndex({"Module":1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 3, "ok" : 0, "errmsg" : "Btree::insert: key too large to index, failing play.logcollection.$Module_1 1100 { : \"RezGainUISystem.Net.WebException: The request was aborted: The request was canceled.\r\n at System.Net.ConnectStream.InternalWrite(Boolean async, Byte...\" }", "code" : 17282 } 请帮助我如何在mongodb中创建索引, 回答1 如果现有文档的索引条目超过索引键限制(1024字节),则MongoDB不会在集合上创建索引。 但是,您可以改为创建哈希索引或文本索引: db.logcollection.createIndex({"Module":"hashed"}) 或者 db.logcollection
  • 如何从一个字符串中获取第一个x字符,而不切断最后一个单词?(How to get first x chars from a string, without cutting off the last word?)
    问题 我在变量中有以下字符串。 Stack Overflow is as frictionless and painless to use as we could make it. 我想从上面的行中获取前28个字符,因此通常如果我使用substr,它将给我Stack Overflow is as frictio该输出一样,但是我希望输出为: Stack Overflow is as... PHP中是否有任何预制函数可以执行此操作,或者请向我提供此代码在PHP中? 编辑: 我想要从字符串中总共28个字符而不打断一个单词,如果它返回的字符数少于28个而不会打断一个单词,那很好。 回答1 您可以使用wordwrap()函数,然后在换行符上爆炸并开始第一部分: $str = wordwrap($str, 28); $str = explode("\n", $str); $str = $str[0] . '...'; 回答2 从AlfaSky: function addEllipsis($string, $length, $end='…') { if (strlen($string) > $length) { $length -= strlen($end); $string = substr($string, 0, $length); $string .= $end; } return
  • 如何在HTTP中编码Content-Disposition标头的filename参数?(How to encode the filename parameter of Content-Disposition header in HTTP?)
    问题 想要强制下载而不是直接在Web浏览器中呈现资源的Web应用程序在以下形式的HTTP响应中发出Content-Disposition标头: Content-Disposition: attachment; filename=FILENAME filename参数可用于建议浏览器将资源下载到其中的文件的名称。 但是,RFC 2183(内容处置)在第2.3节(文件名参数)中指出,文件名只能使用US-ASCII字符: 当前的[RFC 2045]语法将参数值(以及因此的Content-Disposition文件名)限制为US-ASCII。 我们认识到允许在文件名中使用任意字符集的巨大愿望,但是定义必要的机制超出了本文档的范围。 但是,有经验证据表明,当今大多数流行的Web浏览器似乎都允许使用非US-ASCII字符,但是(由于缺乏标准)对文件名的编码方案和字符集规范存在分歧。 那么问题是,如果文件名“naïvefile”(不带引号,并且第三个字母为U + 00EF)需要编码到Content-Disposition标头中,那么流行的浏览器采用了哪些不同的方案和编码? 出于这个问题的目的,流行的浏览器是: 火狐浏览器 IE浏览器苹果浏览器谷歌浏览器歌剧 回答1 在提议的RFC 5987“超文本传输​​协议(HTTP)标头字段参数的字符集和语言编码”中,对此进行了讨论
  • wordwrap a very long string
    How can you display a long string, website address, word or set of symbols with automatic line breaks to keep a div width? I guess a wordwrap of sorts. Usually adding a space works but is there a CSS solution such as word-wrap? For example it (very nastily) overlaps divs, forces horizontal scrolling etc. wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww What can I add to the above string to fit it neatly within a few lines in a div or within the browser window?
  • How to implement wordwrap on jqGrid which works on IE7, IE8 and FF
    How to implement wordwrap on jqGrid which works on IE7, IE8 and FF, while also having column-resize work (grid aligns correctly). Tried to innerwrap content on each td with a div of specific width (based on initial TH width), but colresize will not work on the divs I've inserted. jqGrid calculates the widths of the resized TH and adjacent THs though. Is there a better solution which will avoid all the JavaScript 'hacks'?
  • Wordwrap / Cut Text in HTML string
    here what i want to do : i have a string containing HTML tags and i want to cut it using the wordwrap function excluding HTML tags. I'm stuck : public function textWrap($string, $width) { $dom = new DOMDocument(); $dom->loadHTML($string); foreach ($dom->getElementsByTagName('*') as $elem) { foreach ($elem->childNodes as $node) { if ($node->nodeType === XML_TEXT_NODE) { $text = trim($node->nodeValue); $length = mb_strlen($text); $width -= $length; if($width <= 0) { // Here, I would like to delete all next nodes // and cut the current nodeValue and finally return the string } } } } } I'm not
  • UTF-8一路过关斩将(UTF-8 all the way through)
    问题 我正在设置一台新服务器,并希望在我的Web应用程序中完全支持UTF-8。 我过去曾在现有服务器上尝试过此操作,但最终似乎总是不得不退回到ISO-8859-1。 我到底需要在哪里设置编码/字符集? 我知道我需要配置Apache,MySQL和PHP来执行此操作-是否可以遵循一些标准清单,或者对出现不匹配的地方进行故障排除? 这是用于运行Linux 5,PHP,5和Apache 2的新Linux服务器。 回答1 资料储存 在数据库的所有表和文本列上指定utf8mb4字符集。 这使得MySQL在物理上存储和检索以UTF-8本地编码的值。 请注意,如果指定了utf8mb4_*排序规则(没有任何显式字符集),则MySQL将隐式使用utf8mb4编码。 在旧版本的MySQL(<5.5.3)中,不幸的是,您将被迫仅使用utf8 ,后者仅支持Unicode字符的子集。 我希望我在开玩笑。 资料存取: 在您的应用程序代码(例如PHP)中,无论使用utf8mb4数据库访问方法,都需要将连接字符集设置为utf8mb4 。 这样,当MySQL将数据交给您的应用程序时,MySQL不会从其本地UTF-8进行转换,反之亦然。 一些驱动程序提供了自己的配置连接字符集的机制,该机制既可以更新其自身的内部状态,又可以将要在连接上使用的编码通知MySQL-这通常是首选方法。 在PHP中: 如果您使用PHP≥5.3