按固定长度拆分字符串

7

我正在寻找一种方法来将一个Unicode字母数字类型的字符串分割成固定长度。

    992000199821376John Smith          20070603

数组应该像这样:

Array (
 [0] => 99,
 [1] => 2,
 [2] => 00019982,
 [3] => 1376,
 [4] => "John Smith",
 [5] => 20070603
) 

数组数据将会被分成以下几个部分:

    Array[0] - 账户类型 - 必须是2个字符长,
    Array[1] - 账户状态 - 必须是1个字符长,
    Array[2] - 账户ID - 必须是8个字符长,
    Array[3] - 账户设置 - 必须是4个字符长,
    Array[4] - 用户名 - 必须是20个字符长,
    Array[5] - 加入日期 - 必须是8个字符长。

添加标签可以让你的问题更容易被发现。 - Sergey Kalinichenko
不可能在Unicode中完成(仅适用于ASCII)。请参见我的回答。 - Pavel Radzivilovsky
4个回答

4

如果您想避免使用 preg:

$string = '992000199821376John Smith          20070603';
$intervals = array(2, 1, 8, 4, 20, 8);

$start = 0;
$parts = array();

foreach ($intervals as $i)
{
   $parts[] = mb_substr($string, $start, $i);

   $start += $i;
}

使用间隔使得代码更易于维护。对这个解决方案点赞。 - Berry Langerak
抱歉,不起作用。在Unicode的情况下,按代码单元进行分割,而不是字符。 - Pavel Radzivilovsky
那么 $parts[] = mb_substr($string, $start, $i, mb_detect_encoding($string)); 怎么样? - noj
@jonnyynnoj:我认为在这里使用mb_detect_encoding是不可靠的。而且应该计算字形簇,而不是码点。 - Yakov Galka

0
    $s = '992000199821376Николай Шмидт       20070603';

    if (preg_match('~(.{2})(.{1})(.{8})(.{4})(.{20})(.{8})~u', $s, $match))
    {
        list (, $type, $status, $id, $settings, $name, $date) = $match;
    }

0
使用 substr 函数可以很容易地实现这个功能。
$accountDetails = "992000199821376John Smith          20070603";
$accountArray = array(substr($accountDetails,0,2),substr($accountDetails,2,1),substr($accountDetails,3,8),substr($accountDetails,11,4),substr($accountDetails,15,20),substr($accountDetails,35,8));

这应该可以解决问题,除此之外,正则表达式(如akond所建议的)可能是更好的选择(并且更灵活)。 (我认为这仍然是一个可行的备选方案)。


0

无法按您要求拆分Unicode字符串。

没有办法拆分而不使部分无效。 有些代码点没有突出的方式,例如:שׁ是2个代码点(在UTF-8和UTF-16中为4个字节),您无法拆分它,因为它未定义。

当您使用Unicode时,“字符”是一个非常模糊的术语。有代码点、字形等。请参见http://www.utf8everywhere.org上“字符串长度”的部分。


1
Unicode 对于某些事情来说非常好,但是它使字符串处理变得非常复杂。(你确定它是“不可能”的吗?也许只是“非常困难”?) - ghoti
是的,ghoti,所要求的是不可能的。我想我已经解释过为什么了,不是吗? - Pavel Radzivilovsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接