天天看點

Java 中字元串的格式化 - 帥胡

Java 中字元串的格式化

1、格式字元串文法

産生格式化輸出的每個方法都需要格式字元串 和參數清單。格式字元串是一個String,它可以包含固定文本以及一個或多個嵌入的格式說明符。請考慮以下示例:  

[java] view plain copy

  1. Calendar c = Calendar.getInstance();  
  2. String s = String.format("今天是:%1$tY年%1$tm月%1$te日", c);  
此格式字元串是 format 方法的第一個參數。它包含三個格式說明符 "%1$tm"、"%1$te" 和 "%1$tY",它們指出應該如何處理參數以及在文本的什麼地方插入它們。格式字元串的其餘部分是固定文本。 參數清單由傳遞給位于格式字元串之後的方法的所有參數組成。在上述示例中,參數清單的大小為 1,由對象          Calendar                 c 組成。       

1.1、正常類型、字元類型和數值類型的格式說明符的文法

[java] view plain copy

  1. %[argument_index$][flags][width][.precision]conversion  

可選的 argument_index 是一個十進制整數,用于表明參數在參數清單中的位置。第一個參數由 "1$" 引用,第二個參數由 "2$" 引用,依此類推。

可選 flags 是修改輸出格式的字元集。有效标志集取決于轉換類型。

可選 width 是一個非負十進制整數,表明要向輸出中寫入的最少字元數。

可選 precision 是一個非負十進制整數,通常用來限制字元數。特定行為取決于轉換類型。

所需 conversion 是一個表明應該如何格式化參數的字元。給定參數的有效轉換集取決于參數的資料類型。 

1.2、日期和時間類型的格式說明符的文法

[java] view plain copy

  1. %[argument_index$][flags][width]conversion  

可選的 argument_index、flags 和 width 的定義同上。

所需的 conversion 是一個由兩字元組成的序列。第一個字元是 \'t\' 或 \'T\'。第二個字元表明所使用的格式。這些字元類似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的字元。 

1.3、與參數不對應的格式說明符的文法

[java] view plain copy

  1. %[flags][width]conversion  

可選 flags 和 width 的定義同上。

所需的 conversion 是一個表明要在輸出中所插内容的字元。 

2、轉換

轉換可以分為以下幾類:

  1. 正常 - 可應用于任何參數類型
  2. 字元 - 可應用于表示 Unicode 字元的基本類型:char、

    Character

    、byte、

    Byte

    、short 和 

    Short

    。當 

    Character.isValidCodePoint(int)

     傳回 true 時,可将此轉換應用于 int 和 

    Integer

     類型
  3. 數值
    1. 整數 - 可應用于 Java 的整數類型:byte、

      Byte

      、short、

      Short

      、int、

      Integer

      、long、

      Long

       和 

      BigInteger

    2. 浮點 - 可用于 Java 的浮點類型:float、

      Float

      、double、

      Double

       和 

      BigDecimal

  4. 日期/時間 - 可應用于 Java 的、能夠對日期或時間進行編碼的類型:long、

    Long

    Calendar

     和 

    Date

  5. 百分比 - 産生字面值 \'%\' (\'\u0025\')
  6. 行分隔符 - 産生特定于平台的行分隔符 

下表總結了受支援的轉換。由大寫字元(如 \'B\'、\'H\'、\'S\'、\'C\'、\'X\'、\'E\'、\'G\'、\'A\' 和 \'T\')表示的轉換與由相應的小寫字元的轉換等同,根據流行的 

Locale

 規則将結果轉換為大寫形式除外。後者等同于

String.toUpperCase()

 的以下調用:out.toUpperCase()

轉   換 參數類别 說明
\'b\', \'B\' 正常 如果參數 arg 為 null,則結果為 "false"。如果 arg 是一個 boolean 值或 

Boolean

,則結果為 

String.valueOf()

 傳回的字元串。否則結果為 "true"。
\'h\', \'H\' 正常 如果參數 arg 為 null,則結果為 "null"。否則,結果為調用 Integer.toHexString(arg.hashCode()) 得到的結果。
\'s\', \'S\' 正常 如果參數 arg 為 null,則結果為 "null"。如果 arg 實作 

Formattable

,則調用 

arg.formatTo

。否則,結果為調用 arg.toString() 得到的結果。
\'c\', \'C\' 字元 結果是一個 Unicode 字元
\'d\' 整數 結果被格式化為十進制整數
\'o\' 整數 結果被格式化為八進制整數
\'x\', \'X\' 整數 結果被格式化為十六進制整數
\'e\', \'E\' 浮點 結果被格式化為用計算機科學記數法表示的十進制數
\'f\' 浮點 結果被格式化為十進制數
\'g\', \'G\' 浮點 根據精度和舍入運算後的值,使用計算機科學記數形式或十進制格式對結果進行格式化。
\'a\', \'A\' 浮點 結果被格式化為帶有效位數和指數的十六進制浮點數
\'t\', \'T\' 日期/時間 日期和時間轉換字元的字首。請參閱日期/時間轉換。
\'%\' 百分比 結果為字面值 \'%\' (\'\u0025\')
\'n\' 行分隔符 結果為特定于平台的行分隔符

任何未明确定義為轉換的字元都是非法字元,并且都被保留,以供将來擴充使用。

以下日期和時間轉換的字尾字元是為 \'t\' 和 \'T\' 轉換定義的。這些類型相似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的類型。提供其他轉換類型是為了通路特定于 Java 的功能(如将 \'L\' 用作秒中的毫秒)。 

2.1.、格式化時間:

\'H\' 24 小時制的小時,被格式化為必要時帶前導零的兩位數,即 00 - 23。
\'I\' 12 小時制的小時,被格式化為必要時帶前導零的兩位數,即 01 - 12。
\'k\' 24 小時制的小時,即 0 - 23。
\'l\' 12 小時制的小時,即 1 - 12。
\'M\' 小時中的分鐘,被格式化為必要時帶前導零的兩位數,即 00 - 59。
\'S\' 分鐘中的秒,被格式化為必要時帶前導零的兩位數,即 00 - 60 ("60" 是支援閏秒所需的一個特殊值)。
\'L\' 秒中的毫秒,被格式化為必要時帶前導零的三位數,即 000 - 999。
\'N\' 秒中的毫微秒,被格式化為必要時帶前導零的九位數,即 000000000 - 999999999。
\'p\' 特定于語言環境的 上午或下午 标記以小寫形式表示,例如 "am" 或 "pm"。使用轉換字首 \'T\' 可以強行将此輸出轉換為大寫形式。
\'z\' 相對于 GMT 的 RFC 822 格式的數字時區偏移量,例如 -0800。
\'Z\' 表示時區縮寫形式的字元串。Formatter 的語言環境将取代參數的語言環境(如果有)。
\'s\' 自協調世界時 (UTC) 1970 年 1 月 1 日 00:00:00 至現在所經過的秒數,即 Long.MIN_VALUE/1000 與 Long.MAX_VALUE/1000 之間的內插補點。
\'Q\' 自協調世界時 (UTC) 1970 年 1 月 1 日 00:00:00 至現在所經過的毫秒數,即 Long.MIN_VALUE 與 Long.MAX_VALUE 之間的內插補點。 

2.2、格式化日期:

\'B\' 特定于語言環境的月份全稱,例如 "January" 和 "February"。
\'b\' 特定于語言環境的月份簡稱,例如 "Jan" 和 "Feb"。
\'h\' 與 \'b\' 相同。
\'A\' 特定于語言環境的星期幾全稱,例如 "Sunday" 和 "Monday"
\'a\' 特定于語言環境的星期幾簡稱,例如 "Sun" 和 "Mon"
\'C\' 除以 100 的四位數表示的年份,被格式化為必要時帶前導零的兩位數,即 00 - 99
\'Y\' 年份,被格式化為必要時帶前導零的四位數(至少),例如,0092 等于格裡高利曆的 92 CE。
\'y\' 年份的最後兩位數,被格式化為必要時帶前導零的兩位數,即 00 - 99。
\'j\' 一年中的天數,被格式化為必要時帶前導零的三位數,例如,對于格裡高利曆是 001 - 366。
\'m\' 月份,被格式化為必要時帶前導零的兩位數,即 01 - 13。
\'d\' 一個月中的天數,被格式化為必要時帶前導零兩位數,即 01 - 31
\'e\' 一個月中的天數,被格式化為兩位數,即 1 - 31。 

2.3、格式化常見的日期/時間組合:

\'R\' 24 小時制的時間,被格式化為 "%tH:%tM"
\'T\' 24 小時制的時間,被格式化為 "%tH:%tM:%tS"。
\'r\' 12 小時制的時間,被格式化為 "%tI:%tM:%tS %Tp"。上午或下午标記 (\'%Tp\') 的位置可能與語言環境有關。
\'D\' 日期,被格式化為 "%tm/%td/%ty"。
\'F\' ISO 8601 格式的完整日期,被格式化為 "%tY-%tm-%td"。
\'c\' 日期和時間,被格式化為 "%ta %tb %td %tT %tZ %tY",例如 "Sun Jul 20 16:17:00 EDT 1969"。 

任何未明确定義為轉換的字元都是非法字元,并且都被保留,以供将來擴充使用。

3、标志

下表總結了受支援的标志。y 表示該标志受訓示參數類型支援。

标志 正常 字元 整數 浮點 日期/時間 說明
\'-\' y y y y y 結果将是左對齊的。
\'#\' y1 - y3 y - 結果應該使用依賴于轉換類型的替換形式
\'+\' - - y4 y - 結果總是包括一個符号
\'  \' - - y4 y - 對于正值,結果中将包括一個前導空格
\'0\' - - y y - 結果将用零來填充
\',\' - - y2 y5 - 結果将包括特定于語言環境的組分隔符
\'(\' - - y4 y5 - 結果将是用圓括号括起來的負數

1 取決于 

Formattable

 的定義。

2 隻适用于 \'d\' 轉換。

3 隻适用于 \'o\'、\'x\' 和 \'X\' 轉換。

4 對 

BigInteger

 應用 \'d\'、\'o\'、\'x\' 和 \'X\' 轉換時,或者對 byte 及 

Byte

、short 及 

Short

、int 及 

Integer

、long 及 

Long

 分别應用 \'d\' 轉換時适用。

5 隻适用于 \'e\'、\'E\'、\'f\'、\'g\' 和 \'G\' 轉換。

任何未顯式定義為标志的字元都是非法字元,并且都被保留,以供擴充使用。

4、寬度

寬度是将向輸出中寫入的最少字元數。對于行分隔符轉換,不适用寬度,如果提供寬度,則會抛出異常。

5、精度

對于正常參數類型,精度是将向輸出中寫入的最多字元數。

對于浮點轉換 \'e\'、\'E\' 和 \'f\',精度是小數點分隔符後的位數。如果轉換是 \'g\' 或 \'G\',那麼精度是舍入計算後所得數值的所有位數。如果轉換是 \'a\' 或 \'A\',則不必指定精度。

對于字元、整數和日期/時間參數類型轉換,以及百分比和行分隔符轉換,精度是不适用的;如果提供精度,則會抛出異常。 

6、參數索引

參數索引是一個十進制整數,用于表明參數在參數清單中的位置。第一個參數由 "1$" 引用,第二個參數由 "2$" 引用,依此類推。

根據位置引用參數的另一種方法是使用 \'<\' (\'\u003c\') 标志,這将會重用以前格式說明符的參數。例如,以下兩條語句産生的字元相同: 

[java] view plain copy

  1. Calendar c = Calendar.getInstance();  
  2. String s1 = String.format("今天是:%1$tY年%1$tm月%1$te日", c);  
  3. String s2 = String.format("今天是:%1$tY年%<tm月%<te日", c);  

在格式說明符中既不包含參數索引也不包含 \'<\' 标志時使用。每個使用普通索引的格式說明符都配置設定了一個連續隐式索引,配置設定在獨立于顯式索引或相對索引使用的參數清單中。例如:

[java] view plain copy

  1. Formatter formatter = new Formatter();  
  2. System.out.println(formatter.format("%s %s %s %s", "a", "b", "c", "d"));  
  3. //Output: "a b c d"  

可能有一個使用所有索引形式的格式字元串,例如: 

[java] view plain copy

  1. Formatter formatter = new Formatter();  
  2. System.out.println(formatter.format("%2$s %s %<s %s", "a", "b", "c", "d"));  
  3. //Output: "b a a b"  
  4. // "c" 和 "d" 因為沒有被配置設定索引而被忽略了  
Java 中字元串的格式化 - 帥胡