在這邊舉的例子是如何透過正規表示式來檢查時間格式(hh:mm:ss.SSS),輸入的部分需要符合正規表示式,但是若輸入了不完整的資訊,在此的作法是程式會幫您自動轉換,而非一個正規表示式可以通吃所有資料格式!
規則說明如下:
#格式:
hh:mm:ss.SSS => 時:分:秒.毫秒
#輸入:
1. 單一數字如100,表示秒,檢查格式前程式自動轉換成00:01:40
2. 單一數字加小數點如100.333,整數表示秒、小數點表示毫秒,檢查格式前程式自動轉換成00:01:40.333
3. 不完整資訊如01:40,在此表示mm:ss,檢查格式前程式自動轉換成00:01:40
4. 完整資訊如00:01:40,不需做轉換動作!
#輸出:
Match or Not Match
程式說明如下:
首先,請輸入一時間,這個時間會先透過autoAssignFormat進行格式轉換,統一轉成hh:mm:ss的形式,而提供自動轉換的目的在於方便輸入者不需輸入完整的格式。這時也許會疑惑為啥不直接交由正規表示式判斷就好了? 只能說這裡撰寫的正規表示式只單純判斷hh:mm:ss.SSS,頂多輸入的資訊可以接受少輸入毫秒(SSS)!
而自動轉換的方式也很簡易,首先若有兩個冒號則視為輸入hh:mm:ss,但若小於兩個冒號則判斷為mm:ss或ss,此時就會先轉成秒數再重新組成! 因此您可以輸入大於59的秒或分!
再來是呼叫重組成時間格式的code
再來就是matches pattern ([\\d]+):([0-5]\\d):([0-5]\\d\\.?\\d{0,3})的說明
hh的部分不限制0~23
()表示一個group,group之間指定需要有:的符號存在,因此若少於兩個冒號則會不match。
[]內指定須符合那些範圍的字元,若不指定哪一範圍的數字則以\\d表示,+表示不限長度的數字,[0-5]\\d表示 0 ~ 59。
?表示可有可無的狀況,如在這裡是搭配逗點,因此輸入的秒數為整數pass,而浮點數的話由於\\d{0,3}表示0~3組的數字,因此也能夠pass。
DEMO如下:
規則說明如下:
#格式:
hh:mm:ss.SSS => 時:分:秒.毫秒
#輸入:
1. 單一數字如100,表示秒,檢查格式前程式自動轉換成00:01:40
2. 單一數字加小數點如100.333,整數表示秒、小數點表示毫秒,檢查格式前程式自動轉換成00:01:40.333
3. 不完整資訊如01:40,在此表示mm:ss,檢查格式前程式自動轉換成00:01:40
4. 完整資訊如00:01:40,不需做轉換動作!
#輸出:
Match or Not Match
程式說明如下:
首先,請輸入一時間,這個時間會先透過autoAssignFormat進行格式轉換,統一轉成hh:mm:ss的形式,而提供自動轉換的目的在於方便輸入者不需輸入完整的格式。這時也許會疑惑為啥不直接交由正規表示式判斷就好了? 只能說這裡撰寫的正規表示式只單純判斷hh:mm:ss.SSS,頂多輸入的資訊可以接受少輸入毫秒(SSS)!
public static void main(String[] args) {
// TODO Auto-generated method stub
final String PATTERN = "([\\d]+):([0-5]\\d):([0-5]\\d\\.?\\d{0,3})";
Scanner input = new Scanner(System.in);
try {
while(true) {
System.out.println("Please input time: (hh:mm:ss.SSS or ss)");
String time = input.nextLine();
System.out.println("You input: "+time);
time = autoAssignFormat(time);
System.out.println("After convertion: "+time);
if(time.matches(PATTERN)) {
System.out.println("Match!!");
}else {
System.out.println("Not Match!!");
}
System.out.println("=======================================");
}
}catch (NumberFormatException e) {
System.out.println("Convertion error! "+e.getMessage());
}finally {
input.close();
}
}
而自動轉換的方式也很簡易,首先若有兩個冒號則視為輸入hh:mm:ss,但若小於兩個冒號則判斷為mm:ss或ss,此時就會先轉成秒數再重新組成! 因此您可以輸入大於59的秒或分!
private static String autoAssignFormat(String value) throws NumberFormatException{
value = value.trim();
String ch[] = value.split(":", -1);
if(ch.length > 1){
if(ch.length < 3){
return convertToTimeFormat(convertToSec(ch));
}else{
return value;
}
}else{
return convertToTimeFormat(Double.parseDouble(value));
}
}
private static double convertToSec(String unit[]) throws NumberFormatException{
double sec = 0;
int [][]convert = {{1}, {60, 1}};
for(int i = 0 ; i < unit.length ; i++){
sec = sec + (Double.parseDouble(unit[i]) * convert[unit.length - 1][i]);
}
return sec;
}
再來是呼叫重組成時間格式的code
private final static DecimalFormat df = new DecimalFormat("#.###");
private static String convertToTimeFormat(double sec) throws NumberFormatException{
//input value unit is seconds
StringBuilder format = new StringBuilder();
String time[] = new String[3];
time[0] = String.valueOf((int)(sec / 3600));
time[1] = String.valueOf((int)((sec % 3600) / 60));
double ss = sec % 60;
time[2] = df.format(ss);
for(int i = 0 ; i < time.length ; i++){
if(i == 2){
format.append(ss >= 10 ? time[i] : "0"+time[i]);
}else{
format.append(time[i].length() == 1 ? "0"+time[i] : time[i]).append(":");
}
}
return format.toString();
}
再來就是matches pattern ([\\d]+):([0-5]\\d):([0-5]\\d\\.?\\d{0,3})的說明
hh的部分不限制0~23
()表示一個group,group之間指定需要有:的符號存在,因此若少於兩個冒號則會不match。
[]內指定須符合那些範圍的字元,若不指定哪一範圍的數字則以\\d表示,+表示不限長度的數字,[0-5]\\d表示 0 ~ 59。
?表示可有可無的狀況,如在這裡是搭配逗點,因此輸入的秒數為整數pass,而浮點數的話由於\\d{0,3}表示0~3組的數字,因此也能夠pass。
DEMO如下:
留言
張貼留言