在 Java 中,可以透過 \p 表示比對的字元具備某特性(Properties),而 \P 表示不具備某特性。例如,如果想要比對小寫字母的話,基本方式是使用字元類 [a-z],然而,Java 的規則表示式方言中,對於那些 Character.isLowerCase 測試結果會是 true 的字元,可以使用 \p{javaLowerCase}:
jshell> "a".matches("\\p{javaLowerCase}");
$1 ==> true
jshell> "A".matches("\\p{javaLowerCase}");
$2 ==> false
這些方言稱為 java.lang.Character 類,目前有四個:
\p{javaLowerCase}:對應於Character.isLowerCase測試結果\p{javaUpperCase}:對應於Character.isUpperCase測試結果\p{javaWhitespace}:對應於Character.isWhitespace測試結果\p{javaMirrored}:對應於Character.isMirrored測試結果
如果你在意撰寫的規則表示式,未來是否易於轉換至其他場合中使用或被閱讀,使用這些方言當然是不建議的,Java 也支援 POSIX 方括號表示式的字元類,不過是以 \p 表示,例如測試小寫字母:
jshell> "A".matches("\\p{Lower}");
$3 ==> false
jshell> "a".matches("\\p{Lower}");
$4 ==> true
Java 中可用的 POSIX 字元類有:
\p{Lower}:小寫字母[a-z]\p{Upper}:大寫字母[A-Z]\p{ASCII}:全部的 ASCII[\x00-\x7F]\p{Alpha}:字母[\p{Lower}\p{Upper}]\p{Digit}:十進位數字[0-9]\p{Alnum}:字母與數字[\p{Alpha}\p{Digit}]\p{Punct}:標點符號 !“#$%&'()*+,-./:;<=>?@[]^_`{|}~\p{Graph}:可見字元[\p{Alnum}\p{Punct}]\p{Print}:可列印字元[\p{Graph}\x20]\p{Blank}:空白或 Tab[ \t]\p{Cntrl}:控制字元[\x00-\x1F\x7F]\p{XDigit}:十六進位數字[0-9a-fA-F]\p{Space}:全部空白字元[ \t\n\x0B\f\r]
在 Unicode 特性的支援上,也是使用 \p、\P 的方式。
例如〈一般分類特性〉,\p{L} 表示字母(Letter),\p{N} 表示數字(Number)等,可以進一步指定子特性,例如 \p{Lu} 表示大寫字母、\p{Ll} 表示小寫字母:
jshell> "a".matches("\\p{Ll}");
$5 ==> true
jshell> "a".matches("\\p{Lu}");
$6 ==> false
也可以加上 Is,例如 \p{IsL}、\p{IsLu} 等,如果是單字元表示特性,例如 \p{L},可以省略 {} 寫為 \pL;也可以使用 \p{general_category=Lu} 或簡寫為 \p{gc=Lu}。
有的語言可能會使用多種文字來書寫,例如日語就包含了漢字、平假名、片假名等文字,有的語言只使用一種文字,例如泰文。Unicode 將碼點群組為文字(script)特性上,可以使用 IsHan、script=Han 或 sc=Han 的方式來指定特性,例如測試漢字:
jshell> "林".matches("\\p{IsHan}");
$7 ==> true
對於 Unicode 區塊(block),也就是 Unicode 碼點範圍的指定,可以使用 InCJKUnifiedIdeographs、block=CJKUnifiedIdeographs 或 blk=CJKUnifiedIdeographs,例如,測試中文時常用的 Unicode 碼點範圍為 \u4E00-\u9FFF,也就是 CJK Unified Ideographs 的範圍:
jshell> "林".matches("\\p{InCJKUnifiedIdeographs}");
$8 ==> true
在二元特性的指定上,可以於底下文字前加上 Is:
- Alphabetic
- Ideographic
- Letter
- Lowercase
- Uppercase
- Titlecase
- Punctuation
- Control
- White_Space
- Digit
- Hex_Digit
- Join_Control
- Noncharacter_Code_Point
- Assigned
例如:
jshell> "a".matches("\\p{IsLowercase}");
$9 ==> true
預定義與 POSIX 字元類,可以藉由設置旗標 (?U)(對應 Pattern.UNICODE_CHARACTER_CLASS),令其與對應的 Unicode 特性具有一致的表示。例如:
jshell> "林".matches("\\w");
$10 ==> false
jshell> "林".matches("(?U)\\w");
$11 ==> true
\w 原本只用來比對任一 ASCII 字元,設置旗標 (?U) 之後,就可用來比對 Unicode 文字,底下列出設置旗標 (?U) 後的特性對應:
\p{Lower}:小寫字元\p{IsLowercase}\p{Upper}:大寫字元\p{IsUppercase}\p{ASCII}:全部的 ASCII[\x00-\x7F]\p{Alpha}:字母\p{IsAlphabetic}\p{Digit}:十進位數字\p{IsDigit}\p{Alnum}:字母或數字[\p{IsAlphabetic}\p{IsDigit}]\p{Punct}:標點符號\p{IsPunctuation}\p{Graph}:可見字元[^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]\p{Print}:可列印字元[\p{Graph}\p{Blank}&&[^\p{Cntrl}]]\p{Blank}:空白或 Tab[\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d\x85]]\p{Cntrl}:控制字元\p{gc=Cc}\p{XDigit}:十六進位數字[\p{gc=Nd}\p{IsHex_Digit}]\p{Space}:空白字元\p{IsWhite_Space}\d:十進位數字\p{IsDigit}\D:非十進位數字[^\d]\s:空白字元\p{IsWhite_Space}\S:非空白字元[^\s]\w:文字[\p{Alpha}\p{gc=Mn}\p{gc=Me}\p{gc=Mc}\p{Digit}\p{gc=Pc}\p-{IsJoin_Control}]\W:非文字[^\w]

