Apache的EL函数Replace实现中存在的一点不足之处

全文总结:

 

Apache的EL函数replace实现中对于fn:replace的实现过于简陋,不能使用正则表达式。

 

缘起:

 

考虑以下的应用场景:

 

对于新闻评论功能,为了显示真实性,可以将用户的IP信息,加在留言中。但是,保护隐私起见,需要把部分的IP信息隐藏了。如下图,是网易新闻评论的效果:



 

如果是JavaSE引用,替换部分内容,用正则表达式很容易。

public class Test {
	public static void main(String[] args) {
		String ip = "192.168.7.20";

		String result = ip.replaceAll(
				"(\\d{1,3}\\.\\d{1,3}\\.)\\d{1,3}\\.\\d{1,3}", "$1*.*");

		System.out.println(result);
	}
}
输出:
192.168.*.*

 

但是在JSP中该如何做呢?

 

${fn:replace(ip,"(\\d{1,3}\\.\\d{1,3}\\.)\\d{1,3}\\.\\d{1,3}","$1*.*")}
 

结果输出的是:

 

"192.168.7.20"

 

 

应该是正则表达式没有起作用,让我们来看看EL的function是的源码吧。

 

深究:

 

我用的是Apache的JSTL的实现,其源码如下:

 

 public static String replace(
    String input, 
    String substringBefore,
    String substringAfter) 
    {
        if (input == null) input = "";
        if (input.length() == 0) return "";
        if (substringBefore == null) substringBefore = "";
        if (substringBefore.length() == 0) return input;
                
        StringBuffer buf = new StringBuffer(input.length());
        int startIndex = 0;
        int index;
        while ((index = input.indexOf(substringBefore, startIndex)) != -1) {
            buf.append(input.substring(startIndex, index)).append(substringAfter);
            startIndex = index + substringBefore.length();
        }
        return buf.append(input.substring(startIndex)).toString();
    }

 

可以看到,EL的Replace函数,就是将subStringBefore作为普通的字符串(相反在JavaSE的replaceAll方法中,直这可以是一个正则表达式),提供的就是简单的查找并替换的功能。


因此,如果要达到替换的目的,需要采用其他迂回的办法了。O(∩_∩)O~

 

 

个人解决方案:

 


这里我写了个简单的EL函数,可以使用:

 

package study.el.functions;

import java.util.regex.Pattern;

public class MyFunctions {

	private static Pattern ipMask = null;
	private static Pattern phoneMask = null;

	static {
		ipMask = Pattern.compile("(\\d{1,3}\\.\\d{1,3}\\.)\\d{1,3}\\.\\d{1,3}");
		phoneMask = Pattern.compile("(\\d{3})\\d{4}(\\d{3})");
	}

	public static String replaceAll(String source, String regex, String target) {
		if (source == null)
			return "";
		if (regex == null || regex.length() == 0)
			return source;

		return source.replaceAll(regex, target);
	}
	
	public static String ipMask(String source, String symbol) {
		if (symbol == null)
		   symbol = "*";
		return ipMask.matcher(source).replaceAll("$1"+symbol+"."+symbol);
	}
	
	public static String phoneMask(String source, String symbol) {
		if (symbol == null)
		   symbol = "*";
		return phoneMask.matcher(source).replaceAll("$1"+symbol+symbol+symbol+symbol+"$2");
	}
	
}
 

封装成了个jar包,放入lib目录下,即可使用:

 

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="/Myfunctions" prefix="my"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>

		<title>自定义的EL function</title>

		<meta http-equiv="pragma" content="no-cache">
		<meta http-equiv="cache-control" content="no-cache">
		<meta http-equiv="expires" content="0">

	</head>

	<body>
		<%
			request.setAttribute("ip", "193.233.2.12");
			request.setAttribute("phone", "17871994766");
		%>
		ip : ${ip}<br/>
		 用ipMask: ${my:ipMask(ip,"-") }<br/>
		 用replaceAll :${my:replaceAll(ip,"(\\d{1,3}\\.\\d{1,3}\\.)\\d{1,3}\\.\\d{1,3}","$1*.*")}<br/>
		
		phone : ${phone}<br/>
		 用phoneMask:${my:phoneMask(phone,"*") }<br/>
		 用replaceAll: ${my:replaceAll(phone,"(\\d{3})\\d{4}(\\d{3})","$1####$2")}<br/>
		
		
	</body>
</html>

 

输出结果:


使用直接使用正则表达式的话,效率不高,因为每次都需要编译。所以可以考虑写成通用方法的方式,如ipMask、phoneMask。

 

至此,利用EL表达式的扩展功能,达到了目的。 O(∩_∩)O~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值