博學(xué)而篤志,好問(wèn)而近思

          JAVA中正則表達(dá)式使用介紹

                                           JAVA中正則表達(dá)式使用介紹
           

          一、什么是正則表達(dá)式

              正則表達(dá)式是一種可以用于模式匹配和替換的強(qiáng)有力的工具。我們可以在幾乎所有的基于UNIX系統(tǒng)的工具中找到正則表達(dá)式的身影,例如,vi編輯器,PerlPHP腳本語(yǔ)言,以及awksed shell程序等。此外,象JavaScript這種客戶端的腳本語(yǔ)言也提供了對(duì)正則表達(dá)式的支持。

          正則表達(dá)式可以讓用戶通過(guò)使用一系列的特殊字符構(gòu)建匹配模式,進(jìn)行信息的驗(yàn)證。

          此外,它還能夠高效地創(chuàng)建、比較和修改字符串,以及迅速地分析大量文本和數(shù)據(jù)以搜索、移除和替換文本。

          例如:

          二、基礎(chǔ)知識(shí)

          1.1     開(kāi)始、結(jié)束符號(hào)(它們同時(shí)也屬于定位符)

          我們先從簡(jiǎn)單的開(kāi)始。假設(shè)你要寫(xiě)一個(gè)正則表達(dá)式規(guī)則,你會(huì)用到 ^ $ 符號(hào),他們分別是行首符、行尾符。

          例如:/^\d+[0-9]?\d+$/

           

          1.2 句點(diǎn)符號(hào)

           

          假設(shè)你在玩英文拼字游戲,想要找出三個(gè)字母的單詞,而且這些單詞必須以“t”字母開(kāi)頭,以“n”字母結(jié)束。另外,假設(shè)有一本英文字典,你可以用正則表達(dá)式搜索它的全部?jī)?nèi)容。要構(gòu)造出這個(gè)正則表達(dá)式,你可以使用一個(gè)通配符——句點(diǎn)符號(hào)“.”。這樣,完整的表達(dá)式就是“t.n”,它匹配“tan”“ten”“tin”“ton”,還匹配“t#n”“tpn”甚至“t n”,還有其他許多無(wú)意義的組合。這是因?yàn)榫潼c(diǎn)符號(hào)匹配所有字符,包括空格、Tab字符甚至換行符:

           

           

          1.3 方括號(hào)符號(hào)

           

          為了解決句點(diǎn)符號(hào)匹配范圍過(guò)于廣泛這一問(wèn)題,你可以在方括號(hào)(“[]”)里面指定看來(lái)有意義的字符。此時(shí),只有方括號(hào)里面指定的字符才參與匹配。也就是說(shuō),正則表達(dá)式“t[aeio]n”只匹配“tan”“Ten”“tin”“ton”。但“Toon”不匹配,因?yàn)樵诜嚼ㄌ?hào)之內(nèi)你只能匹配單個(gè)字符:

           

           

          1.4 “符號(hào)

           

          如果除了上面匹配的所有單詞之外,你還想要匹配“toon”,那么,你可以使用“|”操作符。“|”操作符的基本意義就是運(yùn)算。要匹配“toon”,使用“t(a|e|i|o|oo)n”正則表達(dá)式。這里不能使用方擴(kuò)號(hào),因?yàn)榉嚼ㄌ?hào)只允許匹配單個(gè)字符;這里必須使用圓括號(hào)“()”

           

           

          1.5 表示匹配次數(shù)的符號(hào)

           

          表一:顯示了表示匹配次數(shù)的符號(hào),這些符號(hào)用來(lái)確定緊靠該符號(hào)左邊的符號(hào)出現(xiàn)的次數(shù):

           
          代碼/語(yǔ)法 說(shuō)明
          * 重復(fù)零次或更多次
          + 重復(fù)一次或更多次
          ? 重復(fù)零次或一次
          {n} 重復(fù)n次
          {n,} 重復(fù)n次或更多次
          {n,m} 重復(fù)n到m次

           

          表二:常用符號(hào)

           
          代碼/語(yǔ)法 相當(dāng)于
          \w [0-9A-Za-z_]
          \W [^0-9A-Za-z_]
          \s [\t\n\r\f]
          \S [^\t\n\r\f]
          \d [0-9]
          \D [^0-9]

          表二中的符號(hào)意義:

          ·         \w

          包括下劃線的字母和數(shù)字。等同于[0-9A-Za-z_]

          若為匹配多字節(jié)字符的正則表達(dá)式時(shí),則也會(huì)匹配日語(yǔ)的全角字符。

          ·         \W

          非字母和數(shù)字。\w以外的單個(gè)字符。

          ·         \s

          空字符。相當(dāng)于[ \t\n\r\f]

          ·         \S

          非空字符。[ \t\n\r\f] 以外的單個(gè)字符。

          ·         \d

          數(shù)字。即[0-9]

          ·         \D

          非數(shù)字。\d以外的單個(gè)字符

          1.6 定位符介紹(用于規(guī)定匹配模式在目標(biāo)對(duì)象中的出現(xiàn)位置

          較為常用的定位符包括: “^”, “$”, “\b” 以及 “\B”。其中,“^”定位符規(guī)定匹配模式必須出現(xiàn)在目標(biāo)字符串的開(kāi)頭,“$”定位符規(guī)定匹配模式必須出現(xiàn)在目標(biāo)對(duì)象的結(jié)尾,\b定位符規(guī)定匹配模式必須出現(xiàn)在目標(biāo)字符串的開(kāi)頭或結(jié)尾的兩個(gè)邊界之一,而“\B”定位符則規(guī)定匹配對(duì)象必須位于目標(biāo)字符串的開(kāi)頭和結(jié)尾兩個(gè)邊界之內(nèi),即匹配對(duì)象既不能作為目標(biāo)字符串的開(kāi)頭,也不能作為目標(biāo)字符串的結(jié)尾。同樣,我們也可以把“^”“$”以及“\b”“\B”看作是互為逆運(yùn)算的兩組定位符。舉例來(lái)說(shuō):
            /^hell/
            因?yàn)樯鲜稣齽t表達(dá)式中包含“^”定位符,所以可以與目標(biāo)對(duì)象中以 “hell”, “hello” “hellhound”開(kāi)頭的字符串相匹配。
            /ar$/
            因?yàn)樯鲜稣齽t表達(dá)式中包含“$”定位符,所以可以與目標(biāo)對(duì)象中以 “car”, “bar” “ar” 結(jié)尾的字符串相匹配。
            /\bbom/
            因?yàn)樯鲜稣齽t表達(dá)式模式以“\b”定位符開(kāi)頭,所以可以與目標(biāo)對(duì)象中以 “bomb”, “bom”開(kāi)頭的字符串相匹配。
            /man\b/
            因?yàn)樯鲜稣齽t表達(dá)式模式以“\b”定位符結(jié)尾,所以可以與目標(biāo)對(duì)象中以 “human”, “woman” “man”結(jié)尾的字符串相匹配。
            為了能夠方便用戶更加靈活的設(shè)定匹配模式,正則表達(dá)式允許使用者在匹配模式中指定某一個(gè)范圍而不局限于具體的字符。例如:
            /[A-Z]/
            上述正則表達(dá)式將會(huì)與從AZ范圍內(nèi)任何一個(gè)大寫(xiě)字母相匹配。
            /[a-z]/
            上述正則表達(dá)式將會(huì)與從az范圍內(nèi)任何一個(gè)小寫(xiě)字母相匹配。
            /[0-9]/
            上述正則表達(dá)式將會(huì)與從09范圍內(nèi)任何一個(gè)數(shù)字相匹配。
            /([a-z][A-Z][0-9])+/
            上述正則表達(dá)式將會(huì)與任何由字母和數(shù)字組成的字符串,如 “aB0” 等相匹配。這里需要提醒用戶注意的一點(diǎn)就是可以在正則表達(dá)式中使用 “()” 把字符串組合在一起。“()”符號(hào)包含的內(nèi)容必須同時(shí)出現(xiàn)在目標(biāo)對(duì)象中。因此,上述正則表達(dá)式將無(wú)法與諸如 “abc”等的字符串匹配,因?yàn)?/span>“abc”中的最后一個(gè)字符為字母而非數(shù)字。
            如果我們希望在正則表達(dá)式中實(shí)現(xiàn)類似編程邏輯中的運(yùn)算,在多個(gè)不同的模式中任選一個(gè)進(jìn)行匹配的話,可以使用管道符 “|”。例如:
            /to|too|2/
            上述正則表達(dá)式將會(huì)與目標(biāo)對(duì)象中的 “to”, “too”, “2” 相匹配。
            正則表達(dá)式中還有一個(gè)較為常用的運(yùn)算符,即否定符 “[^]”。與我們前文所介紹的定位符 “^” 不同,否定符 “[^]”規(guī)定目標(biāo)對(duì)象中不能存在模式中所規(guī)定的字符串。例如:
            /[^A-C]/
            上述字符串將會(huì)與目標(biāo)對(duì)象中除AB,和C之外的任何字符相匹配。一般來(lái)說(shuō),當(dāng)“^”出現(xiàn)在 “[]”內(nèi)時(shí)就被視做否定運(yùn)算符;而當(dāng)“^”位于“[]”之外,或沒(méi)有“[]”時(shí),則應(yīng)當(dāng)被視做定位符。
            最后,當(dāng)用戶需要在正則表達(dá)式的模式中加入元字符,并查找其匹配對(duì)象時(shí),可以使用轉(zhuǎn)義符“\”。例如:
            /Th\*/
            上述正則表達(dá)式將會(huì)與目標(biāo)對(duì)象中的“Th*”而非“The”等相匹配。

          三、正則表達(dá)式規(guī)則的例子

          /^(\d{3}-|\d{4}-)?(\d{8}|\d{7})?$/    //國(guó)內(nèi)電話
          /^[1-9]*[1-9][0-9]*$/    //
          騰訊QQ
          /^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$/
              //email地址
          /^[a-zA-Z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\s*)?$/
            //url
          /^\d+$/
             //非負(fù)整數(shù)
          /^[0-9]*[1-9][0-9]*$/
            //正整數(shù)
          /^((-\\d+)|(0+))$/
            //非正整數(shù)
          /^-[0-9]*[1-9][0-9]*$/
            //負(fù)整數(shù)
          /^-?\\d+$/
               //整數(shù)
          /^\\d+(\\.\\d+)?$/
            //非負(fù)浮點(diǎn)數(shù)
          /^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$/
            //正浮點(diǎn)數(shù)
          /^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$/
            //非正浮點(diǎn)數(shù)
          /^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/
           //負(fù)浮點(diǎn)數(shù)
          /^(-?\\d+)(\\.\\d+)?$/
            //浮點(diǎn)數(shù)
          /^[a-zA-Z]+$/
            //26個(gè)英文字母組成的字符串
          /^[a-z]+$/
            //26個(gè)英文字母的大寫(xiě)組成的字符串
          /^[a-z]+$/
            //26個(gè)英文字母的小寫(xiě)組成的字符串
          /^[a-za-z0-9]+$/
            //由數(shù)字和26個(gè)英文字母組成的字符串
          /^\\w+$/
            //由數(shù)字、26個(gè)英文字母或者下劃線組成的字符串

          /^\d+[.]?\d+$/    //可以有小數(shù)點(diǎn)的任意多數(shù)字(全部為數(shù)字)

          /(?=^[0-9a-zA-Z]{4,20}$)\w*[a-zA-Z]+\w*/   //同時(shí)滿足下面三個(gè)條件

          (1)       數(shù)字和字母(24-20位(3)不能全部是數(shù)字

           

          四、應(yīng)用

          1.應(yīng)用于JavaScript (用來(lái)驗(yàn)證)

          function doCheck(){

           var patrn = /^\d+[.]?\d+$/;

           var vf1 = document.queryForm.f2Text.value; //文本框

           var vf2 = document.queryForm.f4Text.value;

           var vf3 = document.queryForm.f6Text.value;

           

           var va1 = document.queryForm.a2.checked;     //單選按鈕

           var va2 = document.queryForm.a4.checked;

           var va3 = document.queryForm.a6.checked;

           

           if(va1){

              if(!patrn.exec(vf1)){

                alert("請(qǐng)您輸入數(shù)字,如:30 5.8");

                return;

              }

           }

           if(va2){

              if(!patrn.exec(vf2)){

                alert("請(qǐng)您輸入數(shù)字,如:30 5.8");

                return;

              }

           }

           。。。 。。。

          }

           

          2.在Java中的應(yīng)用

          Javajava.util.regex提供對(duì)正則表達(dá)式的支持。而且Java.lang.String類中的replaceAllsplit函數(shù)也是調(diào)用的正則表達(dá)式來(lái)實(shí)現(xiàn)的。

            
          正則表達(dá)式對(duì)字符串的操作主要包括:字符串匹配,指定字符串替換,指定字符串查找和字符串分割。下面就用一個(gè)例子來(lái)說(shuō)明這些操作是如何實(shí)現(xiàn)的:

          <%@ page import="java.util.regex.*"%>;

          <%

           Pattern p=null; //
          正則表達(dá)式

           Matcher m=null; //
          操作的字符串

           boolean b;

           String s=null;

           StringBuffer sb=null;

           int i=0;

           //
          字符串匹配,這是不符合的

            p = Pattern.compile("a*b");

            m = p.matcher("baaaaab");

            b = m.matches();

           out.println(b+"<br>;");

          //
          字符串匹配,這是符合的

            p = Pattern.compile("a*b");

            m = p.matcher("aaaaab");

            b = m.matches();

            out.println(b+"<br>;");

          //
          字符串替換

            p = Pattern.compile("ab");

            m = p.matcher("aaaaab");

            s = m.replaceAll("d");  

            out.println(s+"<br>;");

            p = Pattern.compile("a*b");

            m = p.matcher("aaaaab");

            s = m.replaceAll("d");  

            out.println(s+"<br>;");

            p = Pattern.compile("a*b");

            m = p.matcher("caaaaab");

            s = m.replaceAll("d");  

            out.println(s+"<br>;");

          //
          字符串查找

           p = Pattern.compile("cat");

           m = p.matcher("one cat two cats in the yard");

           sb = new StringBuffer();

           while (m.find()) {

               m.appendReplacement(sb, "dog");

               i++;

           }

           m.appendTail(sb);

           out.println(sb.toString()+"<br>;");

           out.println(i+"<br>;");

           i=0; 

           p = Pattern.compile("cat");

           m = p.matcher("one cat two ca tsi nthe yard");

            sb = new StringBuffer();

           while (m.find()) {

               m.appendReplacement(sb, "dog");

               i++;

           }

           m.appendTail(sb);

           out.println(sb.toString()+"<br>;");

           out.println(i+"<br>;");

           

           

           p = Pattern.compile("cat");

           m = p.matcher("one cat two cats in the yard");

           p=m.pattern();

           m = p.matcher("bacatab");

           b = m.matches();

           out.println(b+"<br>;"); 

           s = m.replaceAll("dog"); 

           out.println(s+"<br>;"); 

           

           i=0;

           p = Pattern.compile("(fds){2,}");

           m = p.matcher("dsa da fdsfds aaafdsafds aaf");

            sb = new StringBuffer();

           while (m.find()) {

               m.appendReplacement(sb, "dog");

               i++;

           }

           m.appendTail(sb);

           out.println(sb.toString()+"<br>;");

           out.println(i+"<br>;");

           

            p = Pattern.compile("cat");

            m = p.matcher("one cat two cats in the yard");

            sb = new StringBuffer();

            while (m.find()) {

               m.appendReplacement(sb, "<font color=\"red\">;cat</font>;");

            }

          m.appendTail(sb);

          out.println(sb.toString()+"<br>;");

          String aa=sb.toString();

          out.println(aa+"<br>;");

          //字符串分割

            p = Pattern.compile("a+");

            String[] a=p.split("caaaaaat");

            for(i=0;i<a.length;i++)

            {

            out.println(a+"<br>;");

            }

            p = Pattern.compile("a+");

            a=p.split("c aa aaaa t",0);

            for(i=0;i<a.length;i++)

            {

            out.println(a+"<br>;");

            }

            p = Pattern.compile(" +");

            a=p.split("c aa    aaaa t",0);

            for(i=0;i<a.length;i++)

            {

            out.println(a+"<br>;");

            }

            p = Pattern.compile("\\+");

            a=p.split("dsafasdfdsafsda+dsagfasdfa+sdafds");

            out.println(a.length+"<br>;");

            for(i=0;i<a.length;i++)

            {

            out.println(a+"<br>;");

            }

          posted on 2007-05-28 12:28 冰川 閱讀(2756) 評(píng)論(2)  編輯  收藏

          評(píng)論

          # re: JAVA中正則表達(dá)式使用介紹 2007-05-29 10:57 terrypang

          不錯(cuò)!很清晰~~~  回復(fù)  更多評(píng)論   

          # re: JAVA中正則表達(dá)式使用介紹 2008-05-17 20:50 goldgood

          寫(xiě)得,很詳細(xì)。有時(shí)間的話,好好看一下。  回復(fù)  更多評(píng)論   


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2007年5月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(14)

          隨筆檔案

          BlogJava的幫助

          朋友的博客

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          快樂(lè)工作—享受生活
          主站蜘蛛池模板: 涞水县| 杭锦后旗| 桦川县| 景泰县| 航空| 井研县| 温州市| 南漳县| 肇源县| 兴山县| 炉霍县| 慈利县| 永福县| 巩义市| 朔州市| 繁昌县| 将乐县| 卢龙县| 香格里拉县| 扎兰屯市| 额敏县| 武胜县| 秭归县| 元朗区| 咸宁市| 克拉玛依市| 宝丰县| 敖汉旗| 宁波市| 宜阳县| 吴川市| 米脂县| 南汇区| 共和县| 伊通| 白银市| 民勤县| 马龙县| 白玉县| 濮阳市| 朝阳县|