联系方式识别(php版本)

 <?php
/**
 * @name   联系方式识别
 * @name   识别出来的数字最长为20位,多组满足需求的数字也都提取出来
 * @author Rohn(253133755@qq.com)
 * @date   2018/4/25
 */
class ContactRecognize
{

    //识别文本
    private $_arr = array();
    //符合条件的数字组合
    private $_box = array();
    //栈数组
    private $_shed = array();

    private $_variation_num = array(
        '①' => 1,
        '②' => 2,
        '③' => 3,
        '④' => 4,
        '⑤' => 5,
        '⑥' => 6,
        '⑦' => 7,
        '⑧' => 8,
        '⑨' => 9,
        '㈠' => 1,
        '㈡' => 2,
        '㈢' => 3,
        '㈣' => 4,
        '㈤' => 5,
        '㈥' => 6,
        '㈦' => 7,
        '㈧' => 8,
        '㈨' => 9,
        '⑴' => 1,
        '⑵' => 2,
        '⑶' => 3,
        '⑷' => 4,
        '⑸' => 5,
        '⑹' => 6,
        '⑺' => 7,
        '⑻' => 8,
        '⑼' => 9,
        'Ⅰ' => 1,
        'Ⅱ' => 2,
        'Ⅲ' => 3,
        'Ⅳ' => 4,
        'Ⅴ' => 5,
        'Ⅵ' => 6,
        'Ⅶ' => 7,
        'Ⅷ' => 8,
        'Ⅸ' => 9,
        //简体中文
        '一' => 1,
        '二' => 2,
        '三' => 3,
        '四' => 4,
        '五' => 5,
        '六' => 6,
        '七' => 7,
        '八' => 8,
        '九' => 9,
        '久' => 9,
        //繁体中文
        '零' => 0,
        '壹' => 1,
        '贰' => 2,
        '叁' => 3,
        '肆' => 4,
        '伍' => 5,
        '陆' => 6,
        '柒' => 7,
        '捌' => 8,
        '玖' => 9,
        //字母
        'o' => 0,
        'O' => 0,
        'l' => 1,
        'I' => 1,
    );

    //最大匹配的数字长度
    const MAX_NUMBER_LENGTH = 6;
    //状态重置的标记
    const FLAG_RESET = 'reset';

    /**
     * ContactRecognize constructor.
     * @param $str
     */
    public function __construct($str){

        $this->_arr = $this->_ch2arr($str);
    }

    /**
     * 识别主体
     * @return mixed
     */
    public function recognize(){

        foreach($this->_arr as $char){

            $number = $this->_formatChar($char);
            //干扰字符,忽略
            if($number === false){
                continue;
            }
            switch($curState){
                case 0:
                    if($number != self::FLAG_RESET){
                        $curState = $this->_moveState($number, $curState);
                    }
                    break;
                case 1:
                case 2:
                case 3:
                case 4:
                    $curState = $this->_setState($number, $curState);
                    break;
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 14:
                case 15:
                case 16:
                case 17:
                case 18:
                case 19:
                    $curState = $this->_setState($number, $curState);
                    break;
                default:
                    //超过20位的不再做检查,直接做判定处理
                    if(!$this->_isExempt()){
                        array_push($this->_box, $this->_shed);
                    }
                    break;
            }
        }
        //结束检查一次,是否可以把最后一组数据放入box中
        $this->_intoBox($curState);
        if(count($this->_box) > 0){
            //return implode('', $this->_shed);
            return json_encode($this->_box);
        }

        return false;
    }

    /**
     * 是否豁免
     * a)豁免重复数字,如555555,6666666666
     */
    private function _isExempt(){

        if($this->_isAllRepeat()){
            return true;
        }
    }

    /**
     * 豁免重复数字,如555555,6666666666
     */
    private function _isAllRepeat(){

        return count(array_count_values(array_slice($this->_shed, -self::MAX_NUMBER_LENGTH))) == 1;
    }

    /**
     * 设置状态位与数字盒子
     * @param $number
     * @param $curState
     * @return int
     */
    private function _setState($number, $curState){

        if($number == self::FLAG_RESET){

            $this->_intoBox($curState);
            $curState = $this->_resetState();
        }else{

            $curState = $this->_moveState($number, $curState);
        }

        return $curState;
    }

    /**
     * 重置之前检查是否是全重复,满足条件加入到box中
     * @param $curState
     */
    private function _intoBox($curState){

        if($curState >= self::MAX_NUMBER_LENGTH){
            if(!$this->_isExempt()){
                array_push($this->_box, $this->_shed);
            }
        }
    }

    /**
     * 状态前移
     * @param $number
     * @param $curState
     * @return mixed
     */
    private function _moveState($number, $curState){

        array_push($this->_shed, $number);
        $curState++;

        return $curState;
    }

    /**
     * 归初始位
     * @return int
     */
    private function _resetState(){

        $this->_shed = array();
        $curState    = 0;

        return $curState;
    }

    /**
     * 字符格式化
     * @param $char
     * @return
     *  number 数字
     *  FLAG_RESET 重置
     *  false 字符豁免忽略
     */
    private function _formatChar($char){

        //普通数字
        if(is_numeric($char)){
            return $char;
        }
        //变种数字
        $rs = $this->_isVariation($char);
        if($rs !== false){
            return $rs;
        }
        //状态重置
        $rs = $this->_isRest($char);
        if($rs !== false){
            return self::FLAG_RESET;
        }

        return false;
    }

    /**
     * 包含是中文、英文大小写重置
     * @param $char
     * @return bool
     */
    private function _isRest($char){

        //英文
        if(preg_match("/[a-zA-Z\s]/", $char)){
            return true;
        }
        //中文
        if(preg_match('/[\x{4e00}-\x{9fa5}]/u', $char) > 0){
            return true;
        }

        return false;
    }

    /**
     * 是否是变种数字
     * @param $char
     * @return bool|mixed
     */
    private function _isVariation($char){

        return isset($this->_variation_num[$char])?$this->_variation_num[$char]:false;
    }

    /**
     * 汉字转字符串
     * @param $str
     * @param string $charset
     * @return array
     */
    private function _ch2arr($str, $charset = 'utf-8'){

        $length = mb_strlen($str, $charset);
        $array  = array();
        for($i = 0; $i < $length; $i++){
            $array[] = mb_substr($str, $i, 1, $charset);
        }

        return $array;
    }
}

//测试
$s = '12资源12 零3456哈哈12Ⅶ 34567@a1234567890O00o001';
$obj = new ContactRecognize($s);
$s   = $obj->recognize();
print_r($s);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 青色天空映不出你美丽轮廓 袅袅炊烟仿不了你纤美身姿 飞鸟拂过天空 不留一丝痕迹 你走过我心田 留下万般情丝 斩不断...
    梦清涵阅读 268评论 0 1
  • 一、我存在的价值 当看到这句:“世界的真相是【万事万物是按照宇宙法则运行的,与个人努力无关】,但你认为人不是存在本...
    上善若水泽万物阅读 206评论 0 0