V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
3132702442
V2EX  ›  PHP

PHP 实现给中文之间加空格问题,有木有大神会的

  •  
  •   3132702442 · 2017-06-07 10:21:13 +08:00 · 5374 次点击
    这是一个创建于 2728 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我要用 PHP 实现给一行字符串中,前面和后面是中文、中文符号的时候就加空格,是英文、数字、英文符号的时候就不加,例子:

    原来:这个是一些什么汉子。
    转后:这 个 是 一 些 什 么 汉 子 。
    -----------------------------------
    原来:这个是 ui 一些什 b 么汉子。
    转后:这 个 是 ui 一 些 什 b 么 汉 子 。
    -----------------------------------
    原来:这个是 ui 一 些 999 什 A 么汉子。
    转后:这 个 是 ui 一 些 999 什 A 么 汉 子 。

    然后 PHP 文件是 gbk 的编码,对于的中文也是 gbk

    19 条回复    2017-06-12 14:56:14 +08:00
    yplam
        1
    yplam  
       2017-06-07 10:35:04 +08:00
    感觉 preg_replace 就可以,用字节序列的方式去匹配
    jarlyyn
        2
    jarlyyn  
       2017-06-07 10:37:01 +08:00
    中文的标准是什么?
    3132702442
        3
    3132702442  
    OP
       2017-06-07 11:15:49 +08:00
    中文的标准是就是这些汉子啥,还有一些汉子的符号,比如《:、“ [等等之类的,不知道我描述对了没
    Nicksxs
        4
    Nicksxs  
       2017-06-07 11:23:04 +08:00
    用结巴分词吧
    maskerTUI
        5
    maskerTUI  
       2017-06-07 11:28:46 +08:00
    preg_replace + 正则匹配可以做到
    3132702442
        6
    3132702442  
    OP
       2017-06-07 12:05:24 +08:00
    结巴分词是什么?
    em70
        7
    em70  
       2017-06-07 12:09:03 +08:00 via Android
    一个正则就搞定了啊,下面是匹配汉字的表达式
    /^[\x{4e00}-\x{9fa5}]+$/u
    KylinRoc
        8
    KylinRoc  
       2017-06-07 12:14:29 +08:00
    3132702442
        9
    3132702442  
    OP
       2017-06-07 14:09:05 +08:00
    @KylinRoc 你提供的这个的话算是单词句子分句吧?
    KylinRoc
        10
    KylinRoc  
       2017-06-07 14:33:53 +08:00
    @3132702442 看错了你的需求……
    3132702442
        11
    3132702442  
    OP
       2017-06-07 14:34:55 +08:00
    @KylinRoc 呃呃
    ic2y
        12
    ic2y  
       2017-06-07 17:06:57 +08:00
    ic2y
        13
    ic2y  
       2017-06-07 17:15:06 +08:00
    @3132702442 跟 gbk utf8 之类的编码相关的,基本都是 mb_xxx 开头的
    wudanyang
        14
    wudanyang  
       2017-06-07 18:41:57 +08:00
    我提供个思路, 将字符串转为数组, 然后对数组的元素判断是否为 [数字 /字母 /符号]:

    ```
    function ch2arr($str)
    {
    $length = mb_strlen($str, 'utf-8');
    $array = [];
    for ($i=0; $i<$length; $i++)
    $array[] = mb_substr($str, $i, 1, 'utf-8');
    return $array;
    }

    $str = '这个是 ui 一些什 b 么汉子。';

    $arr= ch2arr($str);
    var_dump($arr);

    $pattern = '/^[\s\w+]$/';
    foreach ($arr as $key => $value) {
    echo !preg_match($pattern, $value) && !preg_match($pattern, $arr[$key+1]) ? $value.' ' : $value;
    }
    ```

    实际证明, 中文的句号后面都有个空格.
    hanzhao
        15
    hanzhao  
       2017-06-07 19:45:10 +08:00
    $str = '这个是 ui 一 些 999 什 A 么汉子。';

    $str = preg_replace("/([\x{4e00}-\x{9fa5}])/u", "\\1 ", $str);
    $res = preg_replace ( "/\s(?=\s)/","\\1", $str); //这 个 是 ui 一 些 999 什 A 么 汉 子 。

    utf-8 下可行,没试 GBK 下的情况。
    3132702442
        16
    3132702442  
    OP
       2017-06-08 10:24:06 +08:00
    @hanzhao utf 文件下面我有个代码是可行的,但是 gbk 的我还没找到。

    utf8 文件的 php 可行代码:

    ···
    function str_split_unicode($str, $l = 0) {
    if ($l > 0) {
    $ret = array();
    $len = mb_strlen($str, "GBK");
    for ($i = 0; $i < $len; $i += $l) {
    $ret[] = mb_substr($str, $i, $l, "GBK");
    }
    return $ret;
    }
    return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
    }

    $s = '言归正传,我要用 PHP 实现给一行字符 q1 串 gfg 中,前面和后面是中文、中文符 11 号的时候就加 333 空格,是英文、数字、英文符号的时候就不加';
    $a = str_split_unicode($s);
    $asii = range('!', '~');
    $is_ascii = true;
    foreach ($a as $value) {
    if (in_array($value, $asii)) {
    echo $value;
    $is_ascii = true;
    }else{
    echo $is_ascii ? '' : ' ' , $value;
    $is_ascii = false;
    }
    }···
    3132702442
        17
    3132702442  
    OP
       2017-06-08 10:26:28 +08:00
    @wudanyang 嗯,你这思路我基本上也是这么想的,去判断前后是不是中文,然后加空格,然后 gbk 中文这种的不好分割啊,分割之后就是乱码了。
    3132702442
        18
    3132702442  
    OP
       2017-06-12 11:10:45 +08:00
    想结帖了。。。
    3132702442
        19
    3132702442  
    OP
       2017-06-12 14:56:14 +08:00
    最新可行代码:
    ```
    function set_kg_webname($str,$symbol = ' '){
    $sss = '';
    $arr = ch2arr($str);
    foreach ($arr as $i=>$ch){
    if(preg_match('/[\x80-\xff]+/',$ch) && preg_match('/[\x80-\xff]+/',$arr[($i-1)])){
    $sss .=$symbol.$ch;
    } else{
    $sss .=$ch;
    }
    }
    return $sss;
    }

    function ch2arr($str){
    $array = array();
    $hou=array("","","","","");
    $qian=array(" "," ","\t","\n","\r");
    $str = str_replace($qian,$hou,$str);
    $length = mb_strlen($str, 'gbk');
    if($length<9)return $array;
    for ($i=0; $i<$length; $i++)
    $array[] = mb_substr($str, $i, 1, 'gbk');
    return $array;
    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1242 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 132ms · UTC 18:14 · PVG 02:14 · LAX 10:14 · JFK 13:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.