2

我有一个问题,我认为这很简单,但事实证明它非常复杂。

我有一个长的 UTF-8 字符串,它混合了罗马、西欧、日文和韩文字符和标点符号。许多是多字节字符,但有些(我认为)不是。

我需要做两件事:

  1. 确保没有重复的字符(并输出该新字符串,去除欺骗性)。
  2. 随机打乱该新字符串。

(对不起,我似乎无法让代码引用格式正确......)

function uniquechars($string) {
    $l = mb_strlen($string);
    $unique = array();
    for($i = 0; $i < $l; $i++) {
        $char = mb_substr($string, $i, 1);
        if(!array_key_exists($char, $unique))
            $unique[$char] = 0;
        $unique[$char]++;
    }
    $uniquekeys = join('', array_keys($unique));
    return $uniquekeys;
}  

和:

function unicode_shuffle($string)
{
    $len = mb_strlen($string);
    $sploded = array(); 
    while($len-- > 0) { 
        $sploded[] = mb_substr($string, $len, 1);
    }
    shuffle($sploded);
    $shuffled = join('', $sploded);
    return $shuffled;
}

使用有人非常有帮助地提供的这两个函数,我认为我已经准备好了......除了奇怪的是,看起来唯一字符串(没有重复)和随机字符串不包含相同数量的字符。(我从浏览器中突出显示这些字符,然后剪切并粘贴到另一个应用程序中......一个字符串的长度总是与上面的不同,但它通常会有所不同......它甚至不是相同数量的字符得到每次都被截断!)。

对不起,我对 PHP 的了解不够,也不知道自己编写代码来侦查这个问题,但这里到底出了什么问题?似乎只洗一个大长弦应该很容易,但显然它比我想象的要困难得多。是否有另一种更简单的方法来做到这一点?我是否应该先将字符串转换为相应的十六进制数字并对其进行洗牌,然后再转换回 UTF-8?我应该输出到文件而不是屏幕吗?

有人有建议吗?对不起,我对此很陌生,所以我可能只是在做一些非常愚蠢的事情。

4

1 回答 1

2

你可以做的事情要简单得多。

这是一个仅获取字符串中唯一字符的函数:

// returns an array of unique characters from a given string
function getUnique( $string ) {

    $chars = preg_split( '//', $string, -1, PREG_SPLIT_NO_EMPTY );
    $unique = array_unique( $chars );

    return $unique;

}

然后,如果您想重新排列顺序,只需将唯一字符数组传递给shuffle

$shuffled = shuffle( $unique );

编辑:对于多字节字符,这个函数应该可以解决问题(感谢http://php.net/manual/en/function.mb-split.php对正则表达式的帮助):

function getUnique( $string ) {

    $chars = preg_split( '/(?<!^)(?!$)/u', $string ); 
    $unique = array_unique( $chars );

    return $unique;

}
于 2011-03-26T22:50:52.990 回答