1、
$a = 'x2-g8';
$b = 'x2-y7';
echo strnatcasecmp($a, $b);         //输出-1
---------------------------------------------------------------------------------
2、
$a = 'a10a';
$b = 'a010';
echo strnatcasecmp($a, $b);         //输出1
---------------------------------------------------------------------------------
3、
$a = '10a';
$b = '10.0a';
echo strnatcasecmp($a, $b);         //输出1
---------------------------------------------------------------------------------问题:
1、手册中写的是:
Strings can contain several number parts: x2-g8 < x2-y7 < x2-y08 < x8-y8 
in which case numeric fields are separated by nonnumeric characters. Leading spaces are ignored.
这意思不就是说可以忽略前导位置吗?那$a和$b不就是28,27吗?
2、$a和$b不都是10吗?为什么会被认为不同呢?
3、我还是认为$a和$b都是10啊~看了一遍手册中的“字符串自然排序”规则,但是没太看懂,能帮我讲一下字符串自然排序的规则有哪些吗?
另外字符串自然排序和数组用的自然排序(natcasesort())是一个规则吗?谢谢!

解决方案 »

  1.   

    没用过!你可以用数组排序,那就是自然排序!一般是根据拉字字母排序! 中文,可以转成gbk然后排序。转成相应的语言码后, 应可以直接比较大小。
    大小写字母是不同的。
      

  2.   


    #1.字符串首位为0将被忽略,所以你看下面两个例子是不同的的结果echo strnatcasecmp('7','08');   //-1
    echo strnatcasecmp('y7','y08'); //1#2.字符串内的空格将被忽略#3.如果是非数字对上数字,或者非数字对非数字,则以ascii码为准,如果是数字对数字,有两种情况
       a).任意一方数字串以0开头被视为小的一方,比如
          echo strnatcasecmp('y721','y07203'); //1,因为y=y,7 > 0
       b).如果都非0,则数字小的一方为小的一方,比如
          echo strnatcasecmp('y723','y70212'); //1,因为y=y,70212 > 723可以阅读源代码,这部分很容易看懂。
      

  3.   

    http://sourcefrog.net/projects/natsort/
    在手册strnatcasecmp()里面给的连接
      

  4.   

    #3.如果是非数字对上数字,或者非数字对非数字,则以ascii码为准strnatcasecmp函数做字符串比较是逐个逐个字符进行忽略大小写的比较,这点没问题吧?你主贴的第一个
    $a = 'x2-g8';
    $b = 'x2-y7';
    因为前面的x2-相同,又因为g的ascii码小于y的ascii码,所以结果是-1你主贴的第3个
    $a = '10a';
    $b = '10.0a';
    因为a的ascii码比字符.大,所以结果是1.
      

  5.   

    嗯谢谢,我看懂了。
    但是对你写的第一个还是有一些疑问:
    #1.字符串首位为0将被忽略,所以你看下面两个例子是不同的的结果echo strnatcasecmp('7','08'); //-1
    echo strnatcasecmp('y7','y08'); //1这两个结果都是1啊????
      

  6.   

    echo strnatcasecmp('7','08'); //-1
    echo strnatcasecmp('y7','y08'); //1-11$a = 'x2-g8';
    $b = 'x2-y7';
    echo strnatcasecmp($a, $b); //输出-1
    ---------------------------------------------------------------------------------
    2、
    $a = 'a10a';
    $b = 'a010';
    echo strnatcasecmp($a, $b); //输出1
    ---------------------------------------------------------------------------------
    3、
    $a = '10a';
    $b = '10.0a';
    echo strnatcasecmp($a, $b); //输出1-111
    有什么不对的吗?
    字符串比较时时按字节比较,直至对应位不等时,比较相应两字符如果说明文字与此解释不符,请注意一个事实:老外不是上帝
    如果只是理解上的差异,请去打你英语老师的屁股
      

  7.   

    呵呵!谢谢~!
    但是我这里输出的
    echo strnatcasecmp('7','08');
    echo strnatcasecmp('y7','y08');
    两个都是1啊?这是怎么回事?foolbirdflyfirst不是在三楼说“#1.字符串首位为0将被忽略”吗?
      

  8.   

    有这种事?我这里是php5.3.5,你呢?
    root@lake-pc:/var/www# php -version
    PHP 5.3.5-1ubuntu7.4 with Suhosin-Patch (cli) (built: Dec 13 2011 18:25:14) 
    Copyright (c) 1997-2009 The PHP Group
    Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    root@lake-pc:/var/www# php -r "echo strnatcasecmp('7','08').PHP_EOL;"
    -1
    root@lake-pc:/var/www# php -r "echo strnatcasecmp('y7','y08').PHP_EOL;"
    1
      

  9.   

    源代码查看的是php5.3.8的,位置是ext/standard/strnatcmp.c 102行贴一小段出来给你看。。PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case)                                                             
    {
            unsigned char ca, cb; 
            char const *ap, *bp;
            char const *aend = a + a_len,
                               *bend = b + b_len;
            int fractional, result;
            short leading = 1;        if (a_len == 0 || b_len == 0)
                    return a_len - b_len;        ap = a;
            bp = b;
            while (1) {
                    ca = *ap; cb = *bp;                /* skip over leading zeros */
                    /* 去除串头的0字符(任意多个) */
                    while (leading && ca == '0' && (ap+1 < aend) && isdigit(*(ap+1))) {
                            ca = *++ap;
                    }   
    ...
    ...
    ...
      

  10.   

    注意条件里有isdigit(*(ap+1)),也就是说如果串开头是0,且后面跟着数字的才会被skip over掉。
      

  11.   

    我是在WIN下的5.2.6~难道版本不同引起的?
      

  12.   

    只能这么认为了,
    有空我看看win下5.2的源代码