国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
java 正則表達(dá)式的使用
 
2008-07-01 下午 01:41
正則式,正則表達(dá)式,多行匹配,不以某某開頭,不區(qū)分大小寫,2個單元的或操作
]

 

1 多行匹配
2 不以某某開頭 ,比如不以www開頭
3 不區(qū)分大小寫
4 2個單元的或操作,比如 www | 3w 都可以這種

火龍果回答:

1:多行匹配

在默認(rèn)的情況下 . 是不能匹配行結(jié)束符的(行結(jié)束符有 6 個,具體的可以看看 Pattern 的 API DOC)
同樣,可以像不匹配大小寫匹配那樣使用編譯參數(shù):Pattern.DOTALL

如果還得區(qū)分大小寫的話,還得加上上面說到的 Pattern.CASE_INSENSITIVE 這個,舉個例子:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test {

   
public static void main(String[] args) {
        String str
=
               
"<table>                \n" +
               
" <tr>                 \n" +
               
"    <td>               \n" +
               
"       Hello World!    \n" +
               
"    </td>              \n" +
               
" </tr>                \n" +
               
"</table>";
        String regex
= "<td>(.+?)</td>";
        Pattern pattern
= Pattern.compile(regex);
        Matcher matcher
= pattern.matcher(str);
       
while(matcher.find()) {
            System.out.println(matcher.group(
1).trim());
        }       
    }
}

 

上面這個是不能從 str 抽取出東西的,因為 td 的后面帶有換行符,我們只要更改一下:

Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);

這樣就行了,如果 td 還得不區(qū)分大小寫的話,再改成:

Pattern pattern = Pattern.compile(regex, Pattern.DOTALL | Pattern.CASE_INSENSITIVE);

這樣的話,td 哪怕是大寫的這個表達(dá)式都能把 td 之間的字符區(qū)抽取出來。

當(dāng)然和 Pattern.CASE_INSENSITIVE 一樣,Pattern.DOTALL 也有內(nèi)嵌標(biāo)志表達(dá)式,即 (?s)
s 的意思表示 single-line 就是忽略換行符什么的,只看成單行進(jìn)行處理。

這個表達(dá)式使用內(nèi)嵌 (?s) 的話可以改為:

String regex = "(?s)<td>(.+?)</td>";

如果還要不區(qū)分大小寫的話,再加上 i 標(biāo)志:
String regex
= "(?s)(?i)<td>(.+?)</td>";

但這樣顯得很拖沓,可以把它們合并起來:
String regex
= "(?is)<td>(.+?)</td>";    // 秩序無所謂

最后需要說明一下的是,我曾看到過由于不明白 DOTALL,為了讓 . 匹配行結(jié)束符,直接把表達(dá)式寫成:

String regex = "<td>((.|\\s)+?)</td>";

這樣做是極其危險的,由于選擇結(jié)構(gòu)的匹配效率問題,這樣做在比較長的字符串時會造成堆棧溢出,
使程序崩潰,如果使用 DOTALL 或者 (?s) 的話就不會出現(xiàn)這種情況。

2:不以某某開頭 ,比如不以www開頭
public class Test {

   
public static void main(String[] args) {
        String[] strs
= {
               
"abc1232", "wwwadsf",
               
"awwwfas", "wwadfsf",
               
"", "ww", " ", "www"
            };
        String regex
= "(?:(?!^www).)*";
       
for(String str : strs) {
            System.out.printf(
"%-7s %s%n", str, str.matches(regex));
        }
    }
}

(?!X) 專業(yè)名稱為 Negative Lookahead,表示字符間縫隙后面不允許出現(xiàn)的字符,
即匹配字符間的縫隙,如果縫隙后的字符不是 X 的話,那這個縫隙就匹配成功。

舉個例子,aab 和 aac,現(xiàn)有表達(dá)式 aa(?!b) 這時我們能匹配到的字符串是 aac,
因為 aa 的后面的縫隙之后不允許出現(xiàn)字符 b,因此只有 aac 進(jìn)行了匹配。

再來看個示例:
public class Test {
   
public static void main(String[] args) {
        String str
= "AQuickBrownFoxJumpsOverTheLazyDog";
        String[] strs
= str.split("(?<!^)(?=[A-Z])");
       
for(String s : strs) {
            System.out.println(s);
        }
    }
}

根據(jù)大寫字母拆分字符串。當(dāng)然了,這個使用字符串進(jìn)行分析同樣也能進(jìn)行拆分,
但是使用正則表達(dá)式來拆的話更為便捷直觀一些。

在進(jìn)行這種拆分時,由于在拆分后的字符數(shù)不能減少,因此只能使用零寬度的
lookaround 功能進(jìn)行匹配,lookaround 包括四個,即:

(?=X) (?!X) (?<=X) (?<!X)

來看一下這個表達(dá)式:(? <!^)(?=[A-Z])

前面說到過 (?!) 表示縫隙后面不允許出現(xiàn)的東西,而 (? <!) 表示縫隙前不允許出現(xiàn)的東西。
(?=) 表示縫隙后允許出現(xiàn)的東西,(? <=) 表示縫隙前允許出現(xiàn)的東西。

這個表達(dá)式在拆分時,根據(jù)零寬度匹配縫隙進(jìn)行拆分的,這個縫隙必須滿足以下條件:

(? <!^) 表示縫隙不允許前不能是行開始,即縫隙不能出現(xiàn)在首字母的前面。
(?=[A-Z]) 表示縫隙后面允許出現(xiàn) A-Z 的大寫字母。

這時這個表達(dá)式就匹配了下面帶有 | 的縫隙:

A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog
PS:不加 (
?<!^) 的話,會變成:
|A|Quick|Brown|Fox|Jumps|Over|The|Lazy|Dog

根據(jù) split 的功能,正則表達(dá)式處理程序就根據(jù)上面的 | 將字符串給拆分開來了。


3,不區(qū)分大小寫
不加任何限制的匹配是匹配分大小寫的,但是正則表達(dá)式中可以進(jìn)行改變,
有兩種方式:參數(shù)式和內(nèi)嵌式。

來看個示例:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test {

   
public static void main(String[] args) {       
        String str
= "Book";
        Pattern pattern
= Pattern.compile("book");
        Matcher matcher
= pattern.matcher(str);
        System.out.println(matcher.matches());
    }
}

 

上面的這個表達(dá)式 book 是不能匹配字符串 Book 的,這時我們只要給定編譯時的參數(shù)就可以了:

Pattern pattern = Pattern.compile("book", Pattern.CASE_INSENSITIVE);

Pattern.CASE_INSENSITIVE 這是一個 int 類型的常量,值為 2。表示表達(dá)式忽略大小寫進(jìn)行區(qū)配。

如果我們不采用 Pattern 和 Matcher 兩個類來匹配的話,只是使用 String 的 matches 方法的話,
我們就不能指定表達(dá)式的編譯參數(shù)了,這時就需要采用內(nèi)嵌標(biāo)志表達(dá)式了,與 Pattern.CASE_INSENSITIVE
對應(yīng)的內(nèi)嵌標(biāo)志表達(dá)式是 (?i),它有四種形式:
1,(?i)
2,(?-i)
3,(?i:X)
4,(?-i:X)
不帶有 - 的是開標(biāo)志,帶有 - 的是關(guān)標(biāo)志。

把上面的代碼改成這樣:

public class Test {

   
public static void main(String[] args) {       
        String str
= "Book";
        String regex
= "(?i)book";
        System.out.println(str.matches(regex));
    }
}

我們就達(dá)到了同樣的效果,當(dāng)然這樣并不是最好的,因為字符串中只有 B 是大寫的,
我們沒有必要把所有的字符都進(jìn)行不區(qū)分大小寫匹配,我們可以在打開標(biāo)志,用 (?i) 的
第二種形式馬上關(guān)掉它:
String regex = "(?i)b(?-i)ook";

這樣的話,只有 b 是區(qū)分大小寫了,而 (?-i) 后面的還是得區(qū)分大小寫匹配的。這樣寫
可能看上去很不順眼,我們還能使用第 3 種形式直接指定某些字符是不區(qū)分大小寫的。
String regex = "(?i:b)ook";

這樣的表達(dá)式與上面的那個在語義上是相同的。就效率上肯定是優(yōu)于一下子開,一下子關(guān)的。

可見內(nèi)嵌標(biāo)志表達(dá)式要比指定編譯參數(shù)的功能強大許多。

使用建議:如果能確定某些字符的大小寫時,盡量使用已確定的字符,對于不確定的可以采用
(?i:X) 的方式指定。因此打開不區(qū)分大小寫開關(guān)時,對匹配的性能是有一定影響的。

思考一下:String regex = "(?i)b(?-i:oo)k"; 這個表達(dá)式的意思?


另外:第 1 和第 4,我沒看明白需要了解什么,請在下面的樓層中具體地說明一下。

4:2個單元的或操作

| 稱為多選結(jié)構(gòu),用于匹配 | 之中的任何一個,拿你的例子來說明:

import java.util.regex.Matcher;
import java.util.regex.Pattern;public class Test {

   
public static void main(String[] args) {
        String str
=
               
"<img src=\"http://www.google.com/1.gif\"/>\n" +
               
"<img src=\"http://3w.google.com/1.gif\"/>\n" +
               
"<img src=\"http://abc.baidu.com/1.gif\"/>";
        String regex
= "<img\\ssrc=\"http://(?:ww|3)w.google.com/1.gif\"/>";
        Pattern pattern
= Pattern.compile(regex);
        Matcher matcher
= pattern.matcher(str);
       
while(matcher.find()) {
            System.out.println(matcher.group());
        }       
    }
}

 

注意到其中的 (?:ww |3) 在進(jìn)行多選匹配時盡量找出多選中的規(guī)律,以減少多選的字符,
www 和 3w 在最后一個字符可以共用,前面的不一樣。

(?: ) 的意思表示組成一組,如果沒有 (?: ) 這樣的話,表達(dá)式就變成了:

String regex = "<img\\ssrc=\"http://ww|3w.google.com/1.gif\"/>";

這樣的語義完全變掉了, | 是在一組中進(jìn)行選擇,由于上面的那個表達(dá)式中沒有組,就把整個表
達(dá)式作為了一組,使用 | 的話,就進(jìn)行了整個表達(dá)式的多選結(jié)構(gòu)了。這個表達(dá)式的意思是:
匹配 <img ssrc="http://ww 或者是 3w.google.com/1.gif"/>,這樣的結(jié)果并不是我們所要的。

我們僅僅需要在 ww 和 3 之間進(jìn)行選擇,這時只要把 ww 和 3 放在一組中進(jìn)行多選擇就可以了,
變成 (?:ww |3)。

還有,在多選結(jié)構(gòu)中盡量把出現(xiàn)頻率高的放在前面,這樣可以加快匹配速度。

多選結(jié)構(gòu)的效率在傳統(tǒng)型的引擎中是效率低下的,如果是單個字符的選擇,比如 a $ & 之中的一個,
那就不要使用 (?:a |$ |&) 了,可以直接使用字符類 [a$&] 就可以了。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java過濾特殊字符的正則表達(dá)式 - Java - JavaEye論壇
過濾特殊字符
java正則表達(dá)式(2)
JAVA與正則表達(dá)式
java正則表達(dá)式 非捕獲組,捕獲組詳解
java應(yīng)用集錦3:正則表達(dá)式 excel操作之jxl (轉(zhuǎn))
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服