最近框架和爬蟲上常要處理字符串匹配和替換的場景,備忘。html
好比要匹配html文本中的鏈接,例如a href="www.abc.com/xyz/o"須要替換爲a href="www.bing.com?q=o",能夠以下:java
static final String OSCHINA_LINK = "\"(https://www\\.abc\\.net/p/)(.+)\""; static Pattern pattern = Pattern.compile(OSCHINA_LINK); static String BING_SEARCH = "\"https://cn.bing.com/search?q=$2";
可是此時會致使第一個href="以後的文字到最後一個"之間的內容都是連接地址了,由於java正則默認是貪婪模式。要想在第一個"就結束,須要非貪婪模式,也就是加上?,以下:app
static final String OSCHINA_LINK = "\"(https://www\\.abc\\.net/p/)(.+?)\""; static Pattern pattern = Pattern.compile(OSCHINA_LINK); static String BING_SEARCH = "\"https://cn.bing.com/search?q=$2";
Matcher m = pattern.matcher(param.getData().getNewsBody()); StringBuffer sb = new StringBuffer(); // 使用find()方法查找第一個匹配的對象 boolean result = m.find(); // 使用循環將句子裏全部的表找出並替換爲用戶名.表名,再將內容加到sb裏 while (result) { m.appendReplacement(sb, BING_SEARCH); // 繼續查找下一個匹配對象 result = m.find(); } // 最後調用appendTail()方法將最後一次匹配後的剩餘字符串加到sb裏; m.appendTail(sb);
還有一個場景是要在全部給定的關鍵字以前加上前綴,例如"abc,bcf,wdf"替換爲"x.abc,x.bcf,x.wdf",其中關鍵字列表由輸入給定。框架
這個時候就須要分組替換了,用()進行分組。以下:spa
String tel = "18304072984"; // 括號表示組,被替換的部分$n表示第n組的內容 tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"); System.out.print(tel); // output: 183****2984 String one = "hello girl hi hot".replaceFirst("(\\w+)\\s+(\\w+)", "a.$2 a.$1"); String two = "hello girl hi hot".replaceAll("(\\w+)\\s+(\\w+)", "a.$2 a.$1"); System.out.println(one); // a.girl a.hello hi hot System.out.println(two); // a.girl a.hello a.hot a.hi