熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Java中使用正則表達式驗證本地化數據

2022-06-13   來源: Java核心技術 
數據驗證是編寫任何用戶界面時經常要處理的一項雜務Java? 語言的正則表達式支持可以使數據驗證變得更容易您可以定義一個正則表達式用於描述有效數據然後讓 Java 運行時檢查它是否匹配但是有些類型的數據在不同地區有不同的格式而 ResourceBundle 類讓您可以以一種優雅的方式使用特定於地區的數據本文展示如何結合這兩種技術來解決常見的數據輸入問題

  本文討論將正則表達式與 Java ResourceBundle 相結合的一種數據驗證技術Java 語言對正則表達式的支持可以大大簡化數據驗證您可以將數據與正則表達式進行比較如果它們匹配則知道數據是有效的另一方面Java ResourceBundle 包含翻譯好的字符串用於匹配用戶機器上的當前語言和國家設置ResourceBundle 中的字符串通常是出現在應用程序中的文本但是也可以是特定於某個地區的任何東西

  您將實踐一個示例應用程序該應用程序從 ResourceBundles 獲得正則表達式並將它們用於數據驗證通過這種方法就可以用一塊代碼來驗證很多不同類型的數據更妙的是隨著更多 ResourceBundle 的添加還可以驗證更多類型的數據並且不用更改這段代碼中的任何一行

  本文的示例應用程序是在 Eclipse 中用 Visual Editor 構建的Visual Editor 是一種用於構建圖形化界面的開放源碼工具為了構建自己的應用程序您需要在計算機上安裝 Eclipse 和 Visual Editor 包這個示例應用程序只是舉例說明了驗證數據的一種技巧所以這種方法可用於任何 Java 應用程序

  示例應用程序

  我不想花太多的時間討論這個示例應用程序的所有細節我只關注其中的數據驗證方面的技巧這個應用程序驗證輸入到輸入域中的郵政編碼您可能知道在世界的不同地方郵政編碼千差萬別有的是數字有的則包含字母即使同是由數字組成的郵政編碼在不同地方其長度也不盡相同有的國家以特定的模式排列字母和數字而另外一些國家則采用更自由的格式所有這些格式都可以用正則表達式來描述例如在美國郵政編碼是一個五位數後面還可能跟有一個破折號加一個四位數清單 展示了描述這種格式的正則表達式

清單 用於美國郵政編碼的正則表達式

  []{}([]{})?

  除了格式不同外郵政編碼並不總是被稱為郵政編碼例如美國將郵政編碼稱為 ZIP CodeResourceBundle 的一種常見用法就是處理這種類型的與地區有關的差異用於美國的 ResourceBundle 可能包含短語 Enter your ZIP Code而在用於加拿大的 ResourceBundle 中相應的短語可能是 Enter your postal code我在本文中演示的技巧也是從 ResourceBundle 獲得用於有效郵政編碼的正則表達式

  為了使這個示例簡單化您將創建一個只有一個輸入域和一個 Validate 按鈕的 Swing 應用程序用戶在輸入域中輸入文本然後單擊該按鈕如果數據與當前的正則表達式匹配則應用程序顯示一條消息表明郵政編碼有效因為應用程序使用不同的 ResourceBundle所以正則表達式隨著有效數據的規則的變化而變化由於正則表達式是從文本文件中裝載的一個字符串所以當添加對新類型的郵政編碼的支持時不需要更改代碼

  您將在 Eclipse 中使用 Eclipse Visual Editor 和 Eclipse Java Development Tool 的一些特性來構建這個應用程序您可以在幾乎所有開發環境中使用這種技巧這裡的代碼應該可以在任何基於 Eclipse 的產品中運行例如 Rational Application Developer

展示了該應用程序在 Eclipse Visual Editor 中的樣子

Eclipse Visual Editor 中的示例應用程序
Eclipse Visual Editor 中的示例應用程序

  Visual Editor 提供了四種查看應用程序的方式在屏幕的頂端是應用程序的可視化圖像源代碼在底端Eclipse 還提供了兩個視圖 —— Properties 視圖和 Java Beans 視圖 —— 可以通過這兩個視圖來處理應用程序所有這些查看應用程序的方式都是由 Eclipse Modeling Framework (EMF) 控制的由於已經有一些關於 EMF 的完整書籍所以我不會再談更多的細節從程序員的角度來看重要的一點是任何視圖中的變化都會自動發送到其他視圖例如如果您使用 Properties 視圖將一個對象的背景顏色設為綠色那麼可視化圖像和源代碼也會自動更新

  運行初始的示例應用程序

  首先來看一個已經創建好的應用程序 展示了這個應用程序的運行界面

輸入有效數據時的示例應用程序
輸入有效數據時的示例應用程序

  在圖 用戶輸入了有效的數據並單擊了 Validate 按鈕如果數據無效那麼將出現圖 所示的界面

輸入無效數據時的示例應用程序
輸入無效數據時的示例應用程序

  清單 展示了如何使用 清單 中的正則表達式來驗證數據

清單 使用正則表達式

  Pattern pc = pile([]{}([]{})?); Matcher m = pcmatcher(postalCodegetText()); if (mmatches()) { validLabelsetText(Your postal code is valid); validLabelsetForeground(ColorBLUE); } else { validLabelsetText(Your postal code is not valid); validLabelsetForeground(ColorRED); }


  清單 中的兩條反饋消息通常會被翻譯成其他語言您還將通過使用這裡展示的技巧來 翻譯 正則表達式與一般的翻譯不同將正則表達式轉換成國際化版本是數據格式專家的工作而不是語言專家的工作

  具體化字符串

  Eclipse 為代碼的國際化提供了一個方便的特性首先單擊 Source > Externalize Strings如圖 所示

Externalize Strings 主菜單
Externalize Strings... 主菜單

  Eclipse 查看 Java 代碼以發現應該放入到 ResourceBundle 中的字符串您將看到類似圖 所示的對話框

Externalize Strings 對話框
Externalize Strings 對話框

  在圖 中列出的所有字符串中對話框頂部的空白字符串不需要翻譯(反饋消息的初始值是一個空白字符串)取消對第一個字符串的選擇然後單擊 NextFinishEclipse 創建一個新的名為 comibmdeveloperworksMessages 的類這個類從 messagesproperties 文件獲取字符串

  處理國際化代碼

  具體化代碼之後Eclipse 修改初始的類將字符串移入 messagesproperties 文件並創建一個名為 Messages 的新類Messages 類有一個名為 getString() 的靜態方法應用程序將使用該方法來獲得字符串的值

  Messages 類在內部使用 ResourceBundle清單 展示了生成的用於創建 ResourceBundle 的代碼

清單 創建 ResourceBundle

  public class Messages { private static final String BUNDLE_NAME = comibssages; //$NONNLS$ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundlegetBundle(BUNDLE_NAME);


  稍後我將更詳細地談到如何創建 ResourceBundle

  所有字符串的值都在 messagesproperties 文件中如清單 所示

清單 messagesproperties 文件

  LocalizedValidator=News Gothic LocalizedValidator=Validate LocalizedValidator=[]{}([]{})? LocalizedValidator=Your postal code is valid LocalizedValidator=Your postal code is not valid LocalizedValidator=Exit LocalizedValidator=Localized Data Validator LocalizedValidator=Enter your postal code then click Validate:


  從技術上說該文件是 com/ibm/developerworks/messagesproperties但是您不必關心這個細節生成的代碼可以正確無誤地找到該文件

  使用 ResourceBundle 來驗證數據

  當使用 Eclipse Externalize Strings 功能創建 properties 文件時它修改了應用程序以便同時獲取正則表達式和程序中所有其他可翻譯的文本如清單 所示

清單 通過 ResourceBundle 使用正則表達式

  Pattern pc = pile(MessagesgetString(LocalizedValidator)); //$NONNLS$ Matcher m = pcmatcher(postalCodegetText()); if (mmatches()) { validLabelsetText(MessagesgetString(LocalizedValidator)); //$NONNLS$ validLabelsetForeground(ColorBLUE); } else { validLabelsetText(MessagesgetString(LocalizedValidator)); //$NONNLS$ validLabelsetForeground(ColorRED); }


  注意pile() 方法使用 MessagesgetString() 方法來獲得正則表達式的值當需要驗證數據時代碼首先獲得字符串 LocalizedValidator然後使用它來驗證郵政編碼反饋消息也是從 properties 文件獲得的

  如何裝載 properties 文件

  至此主應用程序已經可以使用 翻譯 好的正則表達式了所有字符串的值都來自 messagesproperties 文件那麼如何裝載這些字符串的不同版本呢?答案取決於 ResourceBundle 是如何創建的

  無論何時運行一個 Java 程序它都有一個特定的地區地區由兩個字母的語言代碼和兩個字母的國家代碼來指定這些代碼是由 ISO 標准定義的地區代碼還有一個不常用的變種部分用於更精確地指定特定的地區下面是一些例子


en_US 是 US English 地區
en_CA 是 Canadian English 地區
fr_CA 是 French Canadian 地區
en 是 English 地區
en_US_UNIX 是 US English 地區的 UNIX 變種至於該變種的意義及其用法是由應用程序的編寫者定義的

  當創建一個新的 ResourceBundle 時Java 運行時根據當前的地區查找文件例如如果當前地區是 en_US那麼 Java 運行時依次查找以下文件


    messages_en_USproperties
    messages_enproperties
    messagesproperties

  當 ResourceBundle 收集翻譯好的字符串時在 messages_en_USproperties 中發現的任何字符串都具有比 messages_enproperties 和 messagesproperties 中具有相同名稱的字符串更高的優先級如果運行時沒有發現任何特定於地區的文件那麼它將使用 messagesproperties 中的字符串

  記住創建 ResourceBundle 的代碼指定了文件名 messagesproperties該文件名不會隨著地區的改變而改變這意味著您的代碼也不需要做出更改您只需指定這個文件名Java 運行時可以自動得出應該裝載哪個特定於地區的文件

  特定於地區的 properties 文件

  一個特定於地區的 properties 文件只包含不同於更通用的 properties 文件的字符串例如如果 messages_enproperties 文件包含 LocalizedValidator=What is your favorite color? 這一行那麼 messages_en_GBproperties 文件可能包含 LocalizedValidator=What is your favourite colour?如果只有這個英國化的字符串是 en_GB 地區所特有的那麼 messages_en_GBproperties 文件只需包含這個字符串當代碼向 ResourceBundle 請求任何其他字符串時如果 messages_enproperties 中有這樣的字符串就使用其中的字符串如果 messages_enproperties 文件中沒有那樣的字符串則使用 messagesproperties 中的版本如果這一系列的 properties 文件中都沒有被請求的字符串就會拋出 javautilMissingResourceException 異常

  清單 展示了美國地區的 properties 文件所特有的一些行

清單 en_US(美國)地區特有的值

  LocalizedValidator=Your ZIP Code is valid LocalizedValidator=Your ZIP Code is not valid LocalizedValidator=Enter your ZIP Code then click Validate:


  這裡惟一的變化是使用 ZIP Code 代替 postal code可用默認的正則表達式驗證該數據

  英國的郵政編碼有六種不同的格式還有一個特殊的值 GIR AA如清單 所示(為了便於閱讀清單 中的正則表達式被分成兩行實際上只有一行

清單 en_GB(英國)地區特有的值

  LocalizedValidator= [AZ]([]|[]{}|[AZ][]|[AZ][]{}|[][AZ] |[AZ][][AZ]) [][AZ]{}|GIR AA LocalizedValidator=Enter your postcode then click Validate:


  用於澳大利亞的正則表達式包括州或地區的簡稱需要的空格(一個或兩個)以及一個四位數如清單 所示

清單 en_AU(澳大利亞)地區特有的值

  LocalizedValidator=(ACT|NSW|NT|QLD|SA|TAS|VIC|WA)( | )[]{} LocalizedValidator=Enter your Australian postal code then click Validate:


  加拿大的郵政編碼格式是字母數字字母一個空格數字字母數字如清單 所示

清單 en_CA(加拿大)地區特有的值

  LocalizedValidator=[AZ][][AZ] [][AZ][] LocalizedValidator=Enter your Canadian postal code then click Validate:


  清單 展示了德國地區特有的值德國的郵政編碼是一個五位數

清單 de(德國)地區特有的值

  LocalizedValidator=Validieren LocalizedValidator=[]{} LocalizedValidator=Ihre Postleitzahl ist gültig LocalizedValidator=Ihre Postleitzahl ist ungültig! LocalizedValidator=Beenden LocalizedValidator=NLS Datenvalidatung LocalizedValidator=Geben Sie Ihre Postleitzahl ein


  在運行時設置地區

  現在您已經定義了 properties 文件接下來應該用兩種方法中的一種來測試這些文件第一種方法是在運行應用程序的時候設置 userlanguage 和 untry 這兩個系統屬性在 Eclipse 環境中可以右鍵單擊一個類名然後選擇 Run 菜單如圖 所示

Run 菜單
Run... 菜單

  在 Run 對話框中可以設置 Java VM 選項以改變默認的語言和地區如圖 所示

在 Run 對話框中設置 Java VM 參數
在 Run 對話框中設置 Java VM 參數

  D 選項用於定義系統屬性您可以在命令行中使用相同的語法例如

  java Duserlanguage=en untry=
AU comibmdeveloperworksLocalizedValidator


  第二種方法是在應用程序中設置地區通過 LocalesetDefault() 方法可以在代碼中設置默認的地區清單 展示了如何改變 LocalizedValidator 類的 main() 方法

清單 在應用程序中設置默認的地區

  public static void main(String[] args) { String language = ; String country = ; if (argslength > ) language = args[]; if (argslength > ) country = args[]; LocalesetDefault(new Locale(language country)); LocalizedValidator nv = new LocalizedValidator(); nvshow(); }


  如果在命令行沒有指定參數則使用用戶計算機的默認地區如果沒有命令行參數則代碼 new Locale( ) 只是創建默認的地區

  也可以在 Run 對話框中設置命令行參數如圖 所示

在 Run 對話框中設置命令行參數
在 Run 對話框中設置命令行參數

  圖 展示了指定了參數 en AU 的情況下應用程序的界面

用於澳大利亞地區(en_AU)的示例應用程序
用於澳大利亞地區(en_AU)的示例應用程序

  用參數 de 運行示例應用程序時將得到如圖 所示的界面

用於德國地區(de)的示例應用程序
用於德國地區(de)的示例應用程序

  結束語

  本文展示了如何將正則表達式與 Java 語言的國際化支持相結合來驗證不同類型的本地化數據通過這種技巧您可以支持新的數據類型而不用更改任何代碼例如示例應用程序如果您想添加對波蘭的郵政編碼的支持那麼只需創建一個 messages_plproperties 文件這樣就在沒有更改任何代碼的情況下添加了對新數據類型的支持(如果您想知道的話那麼告訴您用於波蘭的郵政編碼的正則表達式是 []{}?[]{}

  示例應用程序原封不動地使用 Eclipse 生成的 Messages 類這個類能滿足這個例子的要求但是應用程序啟動時會裝載 ResourceBundle並且直到下次運行應用程序時才能重新裝載 ResourceBundle如果您想更改代碼以便動態地改變 ResourceBundle那麼需要修改 Messages 類使它的字段和方法不是靜態的這做起來不難但是您還需要修改和維護 Messagesjava 文件就把這個任務作為練習吧

  還應該認識到Swing 提供了 javaxswingJFormattedTextField 類利用這個類可以為文本域定義一個掩碼例如您可以使用掩碼 (###) #######使用戶只能在文本域中輸入有效的美國的電話號碼您可以使用與這裡相同的技巧來從一個本地化的 ResourceBundle 中獲得掩碼字符串

  JFormattedTextField 類有明顯的優勢因為它可以在用戶輸入時驗證數據為用戶提供直接的反饋但是掩碼字符串不如正則表達式那麼靈活例如您可以為美國的 ZIP Code 編寫掩碼 ##### 或 #########但是不能同時使用這兩個掩碼如果一個掩碼字符串足以處理一組本地化數據類型那麼從 ResourceBundle 獲得掩碼字符串就是本技巧的一個很好的用途


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26288.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.