咱們的項目中須要獲取Git的日誌數據,用到git log命令進行日誌的獲取。Git沒有像SVN那樣,提供定義好的xml格式的日誌文件。可是能夠本身定義格式:git log --pretty=format:"your own format",而後我用本身寫的xml標籤加git提供的一些placeholder生成了相似於xml的日誌文件。主要仍是以爲xml文件比較方便解析。java
而後發現這樣生成的xml日誌文件存在問題:日誌的提交說明(message)是由用戶填寫的,那麼用戶就可能寫入「&」「<」「>」這樣的內容。衆所周知xml裏出現單獨的這些字符是不合法的,該文件是不能被解析的。git
在svn裏,用戶若是在提交說明裏輸入「&」「<」「>」,生成的xml日誌文件會自動把它們轉換成「&」「<」「>「。可是git內部並不知道我定義的格式是xml的,那麼也就不會自動轉換。因此,我生成的git日誌文件後,須要把提交說明<msg></msg>標籤裏的「&」「<」「>」替換爲對應的轉義字符。api
主要的思想是用java.lang.String中的replaceAll(String regex, String replacement)函數進行替換。svn
查了java.util.regex.Pattern
和
函數java.util.regex.Matcher
兩個類的文檔。
thisjava.util.regex.Pattern
組和捕獲:
捕獲組能夠經過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C))) 中,存在四個這樣的組: spa
1
((A)(B(C)))
2
\A
3
(B(C))
4
(C)
組零始終表明整個表達式。日誌
java.util.regex.Matcher
關於替換字符串:code
替換字符串可能包含到之前匹配期間所捕獲的子序列的引用:$g 每次出現時,都將被 group
(g) 的計算結果替換。$ 以後的第一個數始終被視爲組引用的一部分。若是後續的數能夠造成合法組引用,則將被合併到 g 中。只有數字 '0' 到 '9' 被視爲組引用的可能組件。例如,若是第二個組匹配字符串 "foo",則傳遞替換字符串 "$2bar" 將致使 "foobar" 被添加到字符串緩衝區。orm
因此我用了括號和$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&$3$4"獲得的結果就是替換了<msg></msg>中的「&」爲「&」
//因爲每次只能替換掉一個「&」,因此循環執行替換,直到替換後與替換前的字符串相等。
String str1 = "";
while(!str2.equals(str1)){
str1 = str2;
str2 = str1.replaceAll("(<msg>.*)(&(?!amp;))(.*</msg>)", "$1&$3");
}
System.out.println("firstly replace \"&\": "+str2);
//替換「<」
str1 = "";
while(!str2.equals(str1)){
str1 = str2;
str2 = str1.replaceAll("(<msg>.*)(<)(.*</msg>)", "$1<$3");
}
System.out.println("then replace \"<\": "+str2);
//替換「<」
str1 = "";
while(!str2.equals(str1)){
str1 = str2;
str2 = str1.replaceAll("(<msg>.*)(>)(.*</msg>)", "$1>$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&&file2.</msg></logentry>
then replace "<": <logentry revision='1'><msg>In this comment, I fixed a <bug>, and <added> file1&&file2.</msg></logentry>
finally replace ">": <logentry revision='1'><msg>In this comment, I fixed a <bug>, and <added> file1&&file2.</msg></logentry>
從結果能夠看出達到了我想要的效果。因爲沒有在網上搜到相關的解決方案,也不知道該方法是否是經常使用的方法,效率怎麼樣。若是找到更好的方法,再繼續更新。