URL路径匹配算法实现

自定义的Filter里没有excludePath,所以自己写了一个。开始写的时候还把注意力放在路径分隔符 “ / ” 上,后来发现完全没必要。站在更抽象的层次上看无非都是字符串而已。

测试数据:

"https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_6172758863756121562%22%7D&n_type=0&p_from=1"

匹配模式:

"http*://*.baidu.com/*/landingsuper*"

代码如下:

public static boolean matching(String reg, String input) {
		if ("/*".equals(reg))
			return true;
		//按 * 切割字符串
		String[] reg_split = reg.split("\\*");
		int index = 0, reg_len = reg_split.length;
		//b代表匹配模式的最后一个字符是否是 '*' ,因为在split方法下最后一个 * 会被舍弃
		boolean b = reg.charAt(reg.length() - 1) == '*' ? true : false;
		while (input.length() > 0) {
			//如果匹配到最后一段,比如这里reg的landingsuper
			if (index == reg_len) {
				if (b)//如果reg最后一位是 * ,代表通配,后面的就不用管了,返回true
					return true;
				else  //后面没有通配符 * ,但是input长度还没有变成0 (此时input = context=%7B%22nid%22%3...),显然不匹配
					return false;
			}
			String r = reg_split[index++];
			int indexOf = input.indexOf(r);
			if (indexOf == -1)
				return false;
			//前面匹配成功的就可以不用管了,截取掉直接从新地方开始
			input = input.substring(indexOf + r.length());
		}
		return true;
	}

main函数测试:

	public static void main(String[] args) {

		String uri = "https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_6172758863756121562%22%7D&n_type=0&p_from=1";
		String reg = "http*://*.baidu.com/*/landingsuper*";
		long nanoTime = System.nanoTime();
		boolean b = matching(reg, uri);
		long nanoTime2 = System.nanoTime();
		System.err.println(b);
		System.err.println((nanoTime2 - nanoTime) / 1000.0 + "us");

	}

打印结果:

true
367.013us

注意:可以看到该算法时间复杂度并不高,367微妙是在初始化各种参数,然后还要对匹配模式(reg)字符串切割的情况下测得的。而实际上在Filter中像reg"http*://*.baidu.com/*/landingsuper*"这样的匹配模式是在服务器启动的时候一起初始化并且切割好了的,运行的时候直接使用就行,而且使用频繁的代码块编译器会做优化,所以实际上消耗的时间应该会更少

猜你喜欢

转载自blog.csdn.net/qq_37960007/article/details/82896518
今日推荐