2014年7月30日 星期三

Java Regular Expression (URL To Html A Tag)

※這一篇是為了解決特定用途,非URL Regular expression的介紹

需求:將輸入字串 convert URL to Html A Tag,類似Gmail寄信,會自動將URL轉換為Hyperlink

剛開始先找到了這一篇 URL Regular expression
拿到裡面的 Pattern 之後,
我利用 JavaWorld 找到的測試程式進行測試做了些小修改

修改前 https?:\/\/[\w-\.]+(:\d+)?(\/[\w\/\.]*)?(\?\S*)?(#\S*)?
修改後 https?:\/\/[\w-\.]+(:\d+)?\/?([\w\/\.]*)?(\?[\w=&;]*)?(#\w*)?

主要是將 query string 與 hash 的部分改為不允許中文字
避免連結後接續著中文字會被截取
例如:http://aaa.bbb.cc/foo.html?q=bar豬八戒


接著,為了避免取代原本就已是A Tag Href 屬性內的URL,造成重複
例如:<a href="http://aaa.bbb.cc/">aaa</a>

所以在 Pattern 最前面加上判斷非等於(=)、雙引號(")、單引號(')字元的判斷,如下
([^(=\"')])https?:\/\/[\w-\.]+(:\d+)?\/?([\w\/\.-]*)?(\?[\w=&;\.-]*)?(#\w*)?

但是這樣會造成 Matcher group 0 在取得完整的比對結果時,最前面多出一個字元
不過目前沒有想到其他辦法可以直接排除掉,只好留待取代字串時處理
所以加上了小括號(),讓他成為 group 1


好~有了 Pattern ,接下來就直接看程式吧!!  (其實是懶得解說)

private static String replaceUrlToHtml_A_Tag(String patternStr, String inputStr) {
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(inputStr);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String groupStr = matcher.group(0).trim();
String prefix = matcher.group(1);
if(StringUtils.isNotBlank(prefix)) groupStr = groupStr.replace(prefix, "");
String format = "%s<a href=\"%s\">%s</a>";
String replacement = String.format(format, prefix, groupStr, groupStr);
matcher.appendReplacement(sb, replacement);
}
matcher.appendTail(sb);
return sb.toString();
}



以下是我的測試文件
http://aaa.bbb.cc
https://aaa.bbb.cc
aaa http://aaa.bbb.cc
rrrhttp://aaa.bbb.cc
http://aaa.bbb.cc/ bbb
http://aaa.bbb.cc 八戒
http://regexr.com:8080/foo.html abc
http://regexr.com:8080/foo.html?q=bar&amp;abc=123 abc
http://regexr.com:8080/foo.html?q=bar&amp;abc=123#aaa abc
http://regexr.com:8080/#123 abc
www.demo.com
<a href="http://aaa.bbb.cc/">123</a>
<a href="http://aaa.bbb.cc/">aaa</a>
<a href="http://aaa.bbb.cc/">abc</a>
<span style="font-family: tahoma, arial, verdana, sans-serif;">http://regexr.com:8080/foo.html?q=bar&abc=123 abc</span>


其他參考文獻
http://www.regexr.com/ 
http://www.ewdna.com/2011/09/online-regular-expression-tester.html

2014年7月1日 星期二

模擬多執行續同時執行進行測試

/**
 * @author powei.chen
 * 模擬多執行續同時執行進行測試
 */
public class MultiThread {

long startTime;

public static void main(String[] args) {
new MultiThread();
}

public MultiThread() {
startTime = new Date().getTime() + 5000;
for (int i = 0; i < 5; i++) {
Test test = new Test(i);
test.start();
}
}

class Test extends Thread {
private int no;

public Test(int no) {
this.no = no;
try {
Thread.sleep(500);// 此處表示new是需要時間的
} catch (Exception e) {
e.printStackTrace();
}
}

public void run() {
try {
Thread.sleep(startTime - new Date().getTime());// 以此方式達到同步
//TODO 執行測試
System.out.println(no + " : " + new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}

}