/* * 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; } }