替换xml标签里的“&”“<”“>”为转义字符

我们的项目中需要获取Git的日志数据,用到git log命令进行日志的获取。Git没有像SVN那样,提供定义好的xml格式的日志文件。但是可以自己定义格式:git log --pretty=format:"your own format",然后我用自己写的xml标签加git提供的一些placeholder生成了类似于xml的日志文件。主要还是觉得xml文件比较方便解析。

然后发现这样生成的xml日志文件存在问题:日志的提交说明(message)是由用户填写的,那么用户就可能写入“&”“<”“>”这样的内容。众所周知xml里出现单独的这些字符是不合法的,该文件是不能被解析的。

在svn里,用户如果在提交说明里输入“&”“<”“>”,生成的xml日志文件会自动把它们转换成“&amp;”“&lt;”“&gt;“。但是git内部并不知道我定义的格式是xml的,那么也就不会自动转换。所以,我生成的git日志文件后,需要把提交说明<msg></msg>标签里的“&”“<”“>”替换为对应的转义字符。

 

主要的思想是用java.lang.String中的replaceAll(String regex, String replacement)函数进行替换。

查了java.util.regex.Patternjava.util.regex.Matcher两个类的文档。

java.util.regex.Pattern 组和捕获:

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:

1     ((A)(B(C))) 2     \A 3     (B(C)) 4     (C)

组零始终代表整个表达式。

java.util.regex.Matcher关于替换字符串:

替换字符串可能包含到以前匹配期间所捕获的子序列的引用:$g 每次出现时,都将被 group(g) 的计算结果替换。$ 之后的第一个数始终被视为组引用的一部分。如果后续的数可以形成合法组引用,则将被合并到 g 中。只有数字 '0' 到 '9' 被视为组引用的可能组件。例如,如果第二个组匹配字符串 "foo",则传递替换字符串 "$2bar" 将导致 "foobar" 被添加到字符串缓冲区。

所以我用了括号和$g来进行替换:

public void chartReplace(){
		String str2 = "<logentry revision='1'>" +
				"<msg>In this comment, I fixed a <bug>, and <added> file1&&file2.</msg>" +
				"</logentry>";
		System.out.println("original string: "+str2);
		
		//替换“&”:$1表示与(<msg>.*)的匹配子序列;$4表示与(.*</msg>)匹配的。
                     //&(?!amp;)表示匹配&而且后面不是amp;的字符串
		//"$1&amp;$3$4"得到的结果就是替换了<msg></msg>中的“&”为“&amp;”
		//由于每次只能替换掉一个“&”,所以循环执行替换,直到替换后与替换前的字符串相等。
		String str1 = "";
		while(!str2.equals(str1)){
			str1 = str2;
			str2 = str1.replaceAll("(<msg>.*)(&(?!amp;))(.*</msg>)", "$1&amp;$3");
		}
		System.out.println("firstly replace \"&\": "+str2);
		
		//替换“<”
		str1 = "";
		while(!str2.equals(str1)){
			str1 = str2;
			str2 = str1.replaceAll("(<msg>.*)(<)(.*</msg>)", "$1&lt;$3");
		}
		System.out.println("then replace \"<\": "+str2);
		
		//替换“<”
		str1 = "";
		while(!str2.equals(str1)){
			str1 = str2;
			str2 = str1.replaceAll("(<msg>.*)(>)(.*</msg>)", "$1&gt;$3");
		}
		System.out.println("finally replace \">\": "+str2);
	}

输出结果:

original string: <logentry revision='1'><msg>In this comment, I fixed a <bug>, and <added> file1&&file2.</msg></logentry>
firstly replace "&": <logentry revision='1'><msg>In this comment, I fixed a <bug>, and <added> file1&amp;&amp;file2.</msg></logentry>
then replace "<": <logentry revision='1'><msg>In this comment, I fixed a &lt;bug>, and &lt;added> file1&amp;&amp;file2.</msg></logentry>
finally replace ">": <logentry revision='1'><msg>In this comment, I fixed a &lt;bug&gt;, and &lt;added&gt; file1&amp;&amp;file2.</msg></logentry>

从结果可以看出达到了我想要的效果。由于没有在网上搜到相关的解决方案,也不知道该方法是不是常用的方法,效率怎么样。如果找到更好的方法,再继续更新。

 

转载于:https://my.oschina.net/u/178218/blog/55293

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值