JTCR-正則、反射和文字格式化-24 (end)

x-yun發表於2024-04-24

正則

Pattern 類用於定義正規表示式,Matcher 類用於匹配正規表示式。

Pattern 沒有構造器,使用工廠方法 compile() 建立模式(pattern)。

static Pattern compile(String pattern)

它將字串轉換成 Matcher 可以使用的正規表示式。Pattern 的 matcher() 方法建立 Matcher。

Matcher matcher(CharSequence str)

str 表示和模式匹配的字串,CharSequence 介面定義只讀字元序列。

Matcher 沒有構造器,它的方法用於模式匹配操作。如果模式和整個字串匹配,則 matches() 方法返回 true,否則返回 false;如果模式和字串的某個子串匹配,find() 方法返回 true,否則返回 false,該方法可以重複呼叫,每次從上次匹配子串的下一個索引開始;group() 方法返回最後一個匹配的子串;start() 方法返回當前匹配的索引;end() 方法返回當前匹配的下一個索引;replaceAll(String newStr) 方法替換所有匹配的子串,然後返回替換後的字串。

[xyz] 匹配方括號中任意一個字元,可以指定範圍 [a-e],取反使用 ^,比如 [^a-e]. 匹配任意字元。限定符如下

  • + 匹配 1 或多個字元,x+
  • * 匹配 0 或多個字元,x*
  • ? 匹配 0 或 1 個字元,x?
public static void m() {
  Pattern p = Pattern.compile("xyz");
  Matcher m = p.matcher("xyz");
  // true
  boolean f = m.matches();
  
  m = p.matcher("xyza");
  // false 必須整個字串精確匹配
  f = m.matches();
  // 返回 true,存在子串可以匹配
  m.find();
  
  p  = Pattern.compile("txt");
  m = p.matcher("txt345txt");
  // 輸出 
  // 0
  // 6
  while (m.find()) {
    System.out.println(m.start())
  }
}
public static void m() {
  Pattern p = Pattern.compile("w+");
  Matcher m = p.matcher("w ww www");
  // 匹配 1 或多個 w,+ 和前面的字元作為一個整體
  // w
  // ww
  // www
  while (m.find()) {
    System.out.println(m.group());
  }
  
  p = Pattern.compile("e.+d");
  m = p.matcher("end extend");
  // 匹配按照貪婪原則,儘可能長的匹配
  // end extend
 	while (m.find()) {
    System.out.println(m.group());
  }
  
  p = Pattern.compile("e.+?d");
  m = p.matcher("end extend");
  // 加 ? 表示最短匹配
  // end
  // extend
  while (m.find()) {
    System.out.println(m.group());
  }
  
  p = Pattern.compile("[a-z]+");
  m = p.matcher("this is a test");
  // this
  // is
  // a
  // test
  while (m.find()) {
    System.out.println(m.group());
  }
  
  String s = "abc asli aouojl aobso";
  p = Pattern.compile("a.*? ");
  m = p.matcher(s);
  String r = m.replaceAll("b ");
  // b b b aobso
  System.out.println(r);
  
  // one two three four
  p = Pattern.compile("[ ,.]+");
  String[] str = p.split("one two,three.four");
  for (String e : str) {
    System.out.print(e + " ");
  }
}

如果只執行一次模式匹配,可以使用 Pattern 的 matches() 方法。

// pattern 編譯後是否匹配 str 返回 true/false
static boolean matches(String pattern, CharSequence str)

String 的 matches() 方法也可以使用。

// 呼叫該方法的字串是否匹配 pattern
boolean matches(String pattern)

反射

Member 介面定義的方法可以獲取類屬性、構造器或者方法的資訊。

描述
AccessibleObject 繞過預設訪問控制檢查
Array 動態建立和運算元組
Constructor 構造器資訊
Executable Method 和 Constructor 繼承的抽象類
Field 屬性資訊
Method 方法資訊
Modifier 類和方法的訪問修飾符資訊
Parameter 引數資訊
Proxy 支援動態代理類
ReflectPermission 允許反射類的私有和 protected 成員
public static void main(String[] args) {
		try {
			Class<?> class1 = Class.forName("java.awt.Dimension");
			Constructor<?>[] constructors = class1.getConstructors();
			for (int i = 0; i < constructors.length; i++) {
				System.out.println(constructors[i]);
			}
			Field[] fields = class1.getFields();
			Method[] methods = class1.getMethods();
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
}
class Tested {	
	public void pub() {};
	private void pri() {};
	protected void pro() {};
}

public static void m() {
  Tested a = new Tested();
	Class<? extends Tested> class1 = a.getClass();
  // 獲取類自己定義的方法,不包括繼承的方法
	Method[] methods = class1.getDeclaredMethods();
  // 輸出 pub
	for (int i = 0; i < methods.length; i++) {
    // 返回方法的修飾符,以整數表示
		int modifiers = methods[i].getModifiers();
		if (Modifier.isPublic(modifiers)) {
			System.out.println(methods[i].getName());
		}
	}
}

文字格式化

DateFormat 抽象類提供了用於格式化日期和時間的功能。它的 getDateInstance(int style, Locale locale) 方法是過載方法之一,返回的例項用於格式化日期。其中,style 的取值為 DateFormat 定義的 int 常量:DEFAULT/SHORT/MEDIUM/LONG/FULL 中的一個,表示不同形式的日期。locale 則和本地化有關。它的 format(Date d) 方法返回已格式化的日期,型別為 String。

public class DateFormatDemo {

    public static void main(String[] args) {
        Date date = new Date();
        DateFormat df = null;

        df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.CHINA);
        // 23-7-16
        System.out.println(df.format(date));
        df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.CHINA);
        // 2023-7-16
        System.out.println(df.format(date));
        df = DateFormat.getDateInstance(DateFormat.LONG, Locale.CHINA);
        // 2023年7月16日
        System.out.println(df.format(date));
        df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.JAPAN);
        // 2023/07/16
        System.out.println(df.format(date));
        df = DateFormat.getDateInstance(DateFormat.LONG, Locale.KOREA);
        // 2023년 7월 16일 (일)
        System.out.println(df.format(date));
    }
}

它的 getTimeInstance(int style, Locale locale) 方法返回的例項用於格式化時間,引數取值和作用類似於先前所述,此時作用於時間。

public class TimeFormatDemo {

    public static void main(String[] args) {
        Date date = new Date();
        DateFormat df = null;

        df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.CHINA);
        // 下午9:48
        System.out.println(df.format(date));
        df = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.CHINA);
        // 21:48:46
        System.out.println(df.format(date));
        df = DateFormat.getTimeInstance(DateFormat.LONG, Locale.CHINA);
        // 下午09時48分46秒
        System.out.println(df.format(date));

        df = DateFormat.getTimeInstance(DateFormat.LONG, Locale.JAPAN);
        // 21:48:46 CST
        System.out.println(df.format(date));
        df = DateFormat.getTimeInstance(DateFormat.LONG, Locale.KOREA);
        // 오후 9시 48분 46초
        System.out.println(df.format(date));
    }
}

它的 getDateTimeInstance(int style, Locale locale) 方法返回的例項用於格式化日期和時間。

SimpleDateFormat 類是 DateFormat 類的子類,可以自定義日期和時間格式。構造器 SimpleDateFormat(String fmtStr) 中,fmtStr 表示自定義的日期和時間格式。取值如下

符號 說明
a AM 或 PM
d 月中某一天(1-31)
h AM/PM 表示的小時(1-12)
k 一天中某一小時(1-24)
m 一小時中某一分鐘(0-59)
s 一分鐘中某一秒(0-59)
u 一週某一天,1 表示星期一
w 一年中某一週(1-52)
y
z 時區
D 一年中某一天(1-366)
E 一週中某一天(例如,Monday)
public class SimpleDateFormatDemo {
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat sdf = null;
        sdf = new SimpleDateFormat("hh:mm:ss");
        // 10:06:49
        System.out.println(sdf.format(date));

        sdf = new SimpleDateFormat("yyyy MM dd hh:mm:ss zzz");
        // 2023 07 16 10:06:49 CST
        System.out.println(sdf.format(date));

        sdf = new SimpleDateFormat("yyyy MM dd");
        // 2023 07 16
        System.out.println(sdf.format(date));
    }
}

jdk8 引入的表示日期和時間的新類中,LocalDateLocalTimeLocalDateTime 類位於類層次結構的頂層。三者遵循 ISO 8601 規定的公曆標準。它們沒有定義 public 構造器,提供了工廠方法 now() 返回當前系統的日期和時間。

public class DateTimeDemo {
    public static void main(String[] args) {
        LocalDate curDate = LocalDate.now();
        // 2023-07-16
        System.out.println(curDate);
        LocalTime curTime = LocalTime.now();
        // 22:22:52.273
        System.out.println(curTime);
        LocalDateTime cur = LocalDateTime.now();
        // 2023-07-16T22:22:52.273
        System.out.println(cur);
    }
}

LocalDateTime 類的 toLocalDate() 方法和 toLocalTime() 方法分別返回該物件的日期部分和時間部分的引用。

三者的 format(DateTimeFormatter fmt) 方法用於自定義日期和時間格式。**DateTimeFormatter ** 類的物件使用工廠方法獲取,有

static DateTimeFormatter ofLocalizedDate(FormatStyle date);
static DateTimeFormatter ofLocalizedTime(FormatStyle time);
static DateTimeFormatter ofLocalizedDateTime(FormatStyle fmt, FormatStyle date);

根據想要格式化的型別選擇不同的方法。FormatStyle 列舉定義的常量表示不同格式,有

  • FULL
  • LONG
  • MEDIUM
  • SHORT

和前述類似。

public class DateTimeDemo2 {
    public static void main(String[] args) {
        LocalDate curDate = LocalDate.now();
        // 2023年7月16日
        System.out.println(curDate.format(DateTimeFormatter.ofLocalizedDate(
		  FormatStyle.LONG)));
        LocalTime curTime = LocalTime.now();
        // 22:41:15
        System.out.println(curTime.format(DateTimeFormatter.ofLocalizedTime(
		  FormatStyle.MEDIUM)));
        LocalDateTime cur = LocalDateTime.now();
        // 2023年7月16日 星期日 22:41:15
        System.out.println(cur.format(DateTimeFormatter.ofLocalizedDateTime(
		  FormatStyle.FULL, FormatStyle.MEDIUM)));
    }
}

如果想要自定義日期時間格式,使用 DateTimeFormatter 類的 ofPattern(String fmt) 方法,接收自定義日期和時間格式,返回 DateTimeFormatter 物件。如果在格式字串中想要使用普通文字,用單引號將其包裹起來。

public class DateTimeDemo3 {
    public static void main(String[] args) {
        LocalDate curDate = LocalDate.now();
        // 2023 年  07 月 16 日
        System.out.println(curDate.format(
		  DateTimeFormatter.ofPattern(
		    "yyyy '年'  MM '月' dd '日'",
			Locale.CHINA)));
    }
}

LocalDate、LocalTime 和 LocalDateTime 類提供的 parse(CharSequence dtstr) 方法解析字串形式的日期時間預設格式,不符合則丟擲異常。parse(CharSequence str, DateTimeFormatter fmt) 根據 fmt 的格式解析字串。

public class DateTimeDemo4 {
    public static void main(String[] args) {
        LocalDateTime dateTime = LocalDateTime.parse(
		  "2020 06 01 12:30:29",
		  DateTimeFormatter.ofPattern("yyyy MM dd HH:mm:ss"));
        System.out.println(dateTime
		  .format(DateTimeFormatter.ofPattern(
		    "yyyy'年' MM'月' dd'日' hh'時 'mm'分 'ss'秒'",
			Locale.CHINA)));
    }
}

參考

[1] Herbert Schildt, Java The Complete Reference 11th, 2019.

相關文章