2011-03-25 20 views
2

我有一个问题,我认为会很简单,但事实证明它非常复杂。帮助PHP和多字节字符

我有一个很长的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; 
} 

使用这两个功能,一个人很有帮助地提供,我想我都被设置...除了好奇,它似乎是独特的字符串(没有重复)和Shuffled字符串不包含相同数量的字符。 (我从浏览器中突出显示这些字符,然后剪切并粘贴到另一个应用程序中......一个字符串的长度通常与上面的长度不同,但通常情况各不相同......它的字符数量不一样每次都截断!)。

对不起,我对PHP不够了解,也没有关于自己编码来探测这个问题,但是到底什么地方出了问题呢?看起来应该很容易就打乱一个很长的字符串,但显然这比我想象的要困难得多。是否有另一种更简单的方法来做到这一点?我是否应该先将字符串转换为相应的十六进制数字并将其打乱,然后再转换回UTF-8?我应该输出到文件而不是屏幕?

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

+0

格式化代码很简单:在每行前面使用4个空格,并将其识别为代码。请重新格式化您的代码。 – 2011-03-25 22:00:12

+0

我已经这么做了... – apesa 2011-03-25 22:01:50

+0

@apesa:谢谢!我以某种方式认为我必须只在第一行放置4个空格。 – Dave 2011-03-25 23:16:58

回答

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; 

} 
+0

Craig,非常感谢您提供这个...我决定尝试一下这种方式:使用Unicode。可以编辑它以去掉&#uABCD;中的独特模式。格式?无论哪种方式谢谢你的建议!我也会尝试这个,并保持手指交叉! – Dave 2011-03-27 02:43:52

+0

@Dave - 不是问题,希望它有帮助。我用包含中文字符的字符串测试了它,并且它看起来很完美。 (请记住,如果您在浏览器中查看它,请确保您已为输出设置了UTF-8标头,否则看起来不正确)。我不建议尝试使用'&#uABCD;'格式化的字符,因为你只是让它变得更复杂,但我相信你也能够得到一个正则表达式。让我知道事情是否成功。 – 2011-03-27 12:28:01