Package com.alibaba.toolkit.util.regex

Source Code of com.alibaba.toolkit.util.regex.BestMatchStrategy

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.toolkit.util.regex;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import com.alibaba.toolkit.util.collection.Predicate;

/**
* 最佳匹配策略, 总是试图匹配最长的一项. 如果有多项具有相同的匹配长度, 则返回第一个匹配项.
*
* @author Michael Zhou
* @version $Id: BestMatchStrategy.java,v 1.1 2003/07/03 07:26:34 baobao Exp $
*/
public class BestMatchStrategy implements MatchStrategy {
    /** 按匹配长度从大到小排序的比较器. */
    private static final Comparator MATCH_LENGTH_COMPARATOR = new Comparator() {
        public int compare(Object item1, Object item2) {
            return ((MatchItem) item2).length() - ((MatchItem) item1).length();
        }
    };

    /**
     * 试图匹配指定的输入值. 如果成功, 则返回<code>true</code>. 调用者可以通过
     * <code>context.getMatchItem()</code>来取得匹配项.
     *
     * @param context 匹配上下文
     * @return 如果匹配成功, 则返回<code>true</code>
     */
    public boolean matches(MatchContext context) {
        Predicate predicate = context.getPredicate();

        // 如果没有predicate, 则选择使用更高效的策略
        if (predicate == null) {
            return matchWithoutPredicate(context);
        }

        Collection patterns = context.getPatterns();
        List matchItemList = new ArrayList(patterns.size());

        for (Iterator i = patterns.iterator(); i.hasNext(); ) {
            MatchPattern pattern = (MatchPattern) i.next();

            if (pattern.matches(context)) {
                matchItemList.add(context.getLastMatchItem());
            }
        }

        // 不匹配, 则直接返回null
        if (matchItemList.size() == 0) {
            return false;
        }

        // 按匹配长度由大到小排序(稳定)
        Collections.sort(matchItemList, MATCH_LENGTH_COMPARATOR);

        // 通过指定的predicate过滤所有匹配项
        for (Iterator i = matchItemList.iterator(); i.hasNext(); ) {
            MatchItem item = (MatchItem) i.next();

            if (predicate.evaluate(item)) {
                context.setLastMatchItem(item);
                return true;
            }
        }

        return false;
    }

    /**
     * 试图匹配指定的输入值, 不判断predicate, 具有较高的效率.
     *
     * @param context 匹配上下文
     * @return 如果匹配成功, 则返回<code>true</code>
     */
    private boolean matchWithoutPredicate(MatchContext context) {
        MatchItem bestMatchItem = null;
        int bestMatchLength = -1;

        for (Iterator i = context.getPatterns().iterator(); i.hasNext(); ) {
            MatchPattern pattern = (MatchPattern) i.next();

            if (pattern.matches(context)) {
                MatchItem matchItem = context.getLastMatchItem();
                int matchLength = matchItem.length();

                if (matchLength > bestMatchLength) {
                    bestMatchItem = matchItem;
                    bestMatchLength = matchLength;
                }
            }
        }

        if (bestMatchItem != null) {
            context.setLastMatchItem(bestMatchItem);
            return true;
        }

        return false;
    }
}
TOP

Related Classes of com.alibaba.toolkit.util.regex.BestMatchStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.