全文总结:
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~

- 大小: 1.3 KB

- 大小: 2.3 KB
分享到:
相关推荐
JSTL EL扩展了标准的EL,提供了更多的函数和操作符,比如`fn:replace`可以替换字符串中的特定子串,`fn:split`可以将字符串分割成数组。 3. **taglibs-standard-compat-1.2.5.jar** - 这个文件是为了兼容旧版JSP...
- `<fn:replace>`:替换字符串中的部分字符。 - `<fn:length>`:获取字符串长度。 - `<fn:indexOf>`:查找字符串的位置。 #### 四、JSTL EL表达式语言 ##### 4.1 EL表达式语言简介 EL(Expression Language)...
在myEclipse工程文件中,包含了必要的jar文件,这些jar文件通常包含JSP运行所需的Servlet API和其他相关库,如Apache Tomcat的lib目录下的文件。 CKEditor是一个流行的开源富文本编辑器,提供了丰富的文字编辑功能...
- **EL简介**:EL是一种简洁的数据访问语言,专门用于获取数据模型对象中的属性值,无需编写任何Java代码。 - **结合方式**:在JSTL标签中直接使用EL表达式,例如`${user.name}"/>`。 #### 六、JSTL部署与配置 - **...
JSTL 1.1由Apache Jakarta Project实现,可以通过官方站点下载。下载后的JAR文件需要放置在应用服务器(如Tomcat)的`WEB-INF/lib`目录中。此外,还需要将TLD文件(Tag Library Descriptor)放置在`WEB-INF`目录下,...