高效的字符串匹配器
使用场景
String html="......<script type="text/javascript.........</script>""; StringMatcher matcher = new StringMatcher("</script>"); for(int i=0;i<html.length;i++){ matcher.push(html.charAt(i)); if(matcher.isTarget()){ //do something } }
/** * StringMathcer是一个利用了循环链表原理的数组型字符串匹配器. * * Matcher主要是在字符串处理中匹配字串,原理是把字符push到匹配器中 进行比较,匹配器不提供remove(int index)方法,只能放或者清空。 * 用单纯的数组进行匹配时,很容易地,数组会满而导致大量的元素移动操作, 代价交代,用循环链表只需修改两次指针位置即可。 * 为了更多的减少条件判断,在构造方法中就已经让数组处于满的状态。 * * @author maoanapex88@163.com * */ public class StringMatcher { char[] cache; int start; String target; public StringMatcher(String s) { this.target = s; int length = s.length(); cache = new char[length]; start = 0; for (int i = 0; i < cache.length; i++) cache[i] = 128; } public void push(char c) { cache[start++] = c; start %= cache.length; } public boolean isTarget() { if (cache[(start + 1) % cache.length] == 128) return false; int index = 0; for (int i = start; i < cache.length; i++, index++) if (cache[i] != target.charAt(index)) return false; for (int i = 0; i < start; i++, index++) if (cache[i] != target.charAt(index)) return false; return true; } public boolean isTarget(boolean ignoreCase) { if (cache[(start + 1) % cache.length] == 128) return false; int index = 0; for (int i = start; i < cache.length; i++, index++) { if (ignoreCase && cache[i] != target.charAt(index) && cache[i] - target.charAt(index) != 32 && cache[i] - target.charAt(index) != -32) return false; } for (int i = 0; i < start; i++, index++) { if (ignoreCase && cache[i] != target.charAt(index) && cache[i] - target.charAt(index) != 32 && cache[i] - target.charAt(index) != -32) return false; } return true; } /** * clear */ public void clear() { start = 0; for (int i = 0; i < cache.length; i++) cache[i] = 128; } /** * @return */ public int length() { return target.length(); } }