public static void parsePattern(List<NR> nrList, List<Vertex> vertexList, final WordNet wordNetOptimum, final WordNet wordNetAll)
    {
        // 拆分UV
        ListIterator<Vertex> listIterator = vertexList.listIterator();
        StringBuilder sbPattern = new StringBuilder(nrList.size());
        NR preNR = NR.A;
        boolean backUp = false;
        int index = 0;
        for (NR nr : nrList)
        {
            ++index;
            Vertex current = listIterator.next();
//            logger.trace("{}/{}", current.realWord, nr);
            switch (nr)
            {
                case U:
                    if (!backUp)
                    {
                        vertexList = new ArrayList<Vertex>(vertexList);
                        listIterator = vertexList.listIterator(index);
                        backUp = true;
                    }
                    sbPattern.append(NR.K.toString());
                    sbPattern.append(NR.B.toString());
                    preNR = B;
                    listIterator.previous();
                    String nowK = current.realWord.substring(0, current.realWord.length() - 1);
                    String nowB = current.realWord.substring(current.realWord.length() - 1);
                    listIterator.set(new Vertex(nowK));
                    listIterator.next();
                    listIterator.add(new Vertex(nowB));
                    continue;
                case V:
                    if (!backUp)
                    {
                        vertexList = new ArrayList<Vertex>(vertexList);
                        listIterator = vertexList.listIterator(index);
                        backUp = true;
                    }
                    if (preNR == B)
                    {
                        sbPattern.append(NR.E.toString());  //BE
                    }
                    else
                    {
                        sbPattern.append(NR.D.toString());  //CD
                    }
                    sbPattern.append(NR.L.toString());
                    // 对串也做一些修改
                    listIterator.previous();
                    String EorD = current.realWord.substring(0, 1);
                    String L = current.realWord.substring(1, current.realWord.length());
                    listIterator.set(new Vertex(EorD));
                    listIterator.next();
                    listIterator.add(new Vertex(L));
                    continue;
                default:
                    sbPattern.append(nr.toString());
                    break;
            }
            preNR = nr;
        }
        String pattern = sbPattern.toString();
//        logger.trace("模式串：{}", pattern);
//        logger.trace("对应串：{}", vertexList);
//        if (pattern.length() != vertexList.size())
//        {
//            logger.warn("人名识别模式串有bug", pattern, vertexList);
//            return;
//        }
        final Vertex[] wordArray = vertexList.toArray(new Vertex[0]);
        final int[] offsetArray = new int[wordArray.length];
        offsetArray[0] = 0;
        for (int i = 1; i < wordArray.length; ++i)
        {
            offsetArray[i] = offsetArray[i - 1] + wordArray[i - 1].realWord.length();
        }
        trie.parseText(pattern, new AhoCorasickDoubleArrayTrie.IHit<NRPattern>()
        {
            @Override
            public void hit(int begin, int end, NRPattern value)
            {
//            logger.trace("匹配到：{}", keyword);
                StringBuilder sbName = new StringBuilder();
                for (int i = begin; i < end; ++i)
                {
                    sbName.append(wordArray[i].realWord);
                }
                String name = sbName.toString();
//            logger.trace("识别出：{}", name);
                // 对一些bad case做出调整
                switch (value)
                {
                    case BCD:
                        if (name.charAt(0) == name.charAt(2)) return; // 姓和最后一个名不可能相等的
//                        String cd = name.substring(1);
//                        if (CoreDictionary.contains(cd))
//                        {
//                            EnumItem<NR> item = PersonDictionary.dictionary.get(cd);
//                            if (item == null || !item.containsLabel(Z)) return; // 三字名字但是后两个字不在词典中，有很大可能性是误命中
//                        }
                        break;
                }
                if (isBadCase(name)) return;

                // 正式算它是一个名字
                if (HanLP.Config.DEBUG)
                {
                    System.out.printf("识别出人名：%s %s\n", name, value);
                }
                int offset = offsetArray[begin];
                wordNetOptimum.insert(offset, new Vertex(Predefine.TAG_PEOPLE, name, ATTRIBUTE, WORD_ID), wordNetAll);
            }
        });
    }
public static void parsePattern ( List < NR > nrList , List < Vertex > vertexList , final WordNet wordNetOptimum , final WordNet wordNetAll ) { ListIterator < Vertex > listIterator = vertexList . listIterator ( ) ; StringBuilder sbPattern = new StringBuilder ( nrList . size ( ) ) ; NR preNR = NR . A ; boolean backUp = false ; int index = 0 ; for ( NR nr : nrList ) { ++ index ; Vertex current = listIterator . next ( ) ; switch ( nr ) { case U : if ( ! backUp ) { vertexList = new ArrayList < Vertex > ( vertexList ) ; listIterator = vertexList . listIterator ( index ) ; backUp = true ; } sbPattern . append ( NR . K . toString ( ) ) ; sbPattern . append ( NR . B . toString ( ) ) ; preNR = B ; listIterator . previous ( ) ; String nowK = current . realWord . substring ( 0 , current . realWord . length ( ) - 1 ) ; String nowB = current . realWord . substring ( current . realWord . length ( ) - 1 ) ; listIterator . set ( new Vertex ( nowK ) ) ; listIterator . next ( ) ; listIterator . add ( new Vertex ( nowB ) ) ; continue ; case V : if ( ! backUp ) { vertexList = new ArrayList < Vertex > ( vertexList ) ; listIterator = vertexList . listIterator ( index ) ; backUp = true ; } if ( preNR == B ) { sbPattern . append ( NR . E . toString ( ) ) ; } else { sbPattern . append ( NR . D . toString ( ) ) ; } sbPattern . append ( NR . L . toString ( ) ) ; listIterator . previous ( ) ; String EorD = current . realWord . substring ( 0 , 1 ) ; String L = current . realWord . substring ( 1 , current . realWord . length ( ) ) ; listIterator . set ( new Vertex ( EorD ) ) ; listIterator . next ( ) ; listIterator . add ( new Vertex ( L ) ) ; continue ; default : sbPattern . append ( nr . toString ( ) ) ; break ; } preNR = nr ; } String pattern = sbPattern . toString ( ) ; final Vertex [ ] wordArray = vertexList . toArray ( new Vertex [ 0 ] ) ; final int [ ] offsetArray = new int [ wordArray . length ] ; offsetArray [ 0 ] = 0 ; for ( int i = 1 ; i < wordArray . length ; ++ i ) { offsetArray [ i ] = offsetArray [ i - 1 ] + wordArray [ i - 1 ] . realWord . length ( ) ; } trie . parseText ( pattern , new AhoCorasickDoubleArrayTrie . IHit < NRPattern > ( ) { @ Override public void hit ( int begin , int end , NRPattern value ) { StringBuilder sbName = new StringBuilder ( ) ; for ( int i = begin ; i < end ; ++ i ) { sbName . append ( wordArray [ i ] . realWord ) ; } String name = sbName . toString ( ) ; switch ( value ) { case BCD : if ( name . charAt ( 0 ) == name . charAt ( 2 ) ) return ; break ; } if ( isBadCase ( name ) ) return ; if ( HanLP . Config . DEBUG ) { System . out . printf ( "识别出人名：%s %s\n" , name , value ) ; } int offset = offsetArray [ begin ] ; wordNetOptimum . insert ( offset , new Vertex ( Predefine . TAG_PEOPLE , name , ATTRIBUTE , WORD_ID ) , wordNetAll ) ; } } ) ; }
模式匹配

@param nrList         确定的标注序列
@param vertexList     原始的未加角色标注的序列
@param wordNetOptimum 待优化的图
@param wordNetAll     全词图