JAVA學習第六十五課 — Regex,javaRegex

來源:互聯網
上載者:User

JAVA學習第六十五課 — Regex,javaRegex

Regex:主要應用於操作字串,通過一些特定的符號來體現

舉例:

QQ號的校正

6~9位,0不得開頭,必須是數字

String類中有matches方法

matches(String regex)
告知此字串是否匹配給定的Regex。

regex,就是給定的Regex

public static void checkQQ() {//第一位是數字1-9,第二位以後是0-9,除去第一位元剩下數字位元範圍是5到8位String regex = "[1-9][0-9]{5,8}";//RegexString qq = "123459";boolean flag = qq.matches(regex);System.out.println(qq+" : "+flag);}

PS:Regex雖然簡化了書寫,但是代碼的閱讀性極差

符號意義

Regex難就難在符號太多。

預定義字元類
. 任何字元(與行結束符可能匹配也可能不匹配)
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 空白字元:[ \t\n\x0B\f\r]
\S 非空白字元:[^\s]
\w 單詞字元:[a-zA-Z_0-9]
\W 非單詞字元:[^\w]
字元類
[abc] a、b 或 c(簡單類)
[^abc] 任何字元,除了 a、b 或c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](並集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](減去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去)

邊界匹配器
^ 行的開頭
$ 行的結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個匹配的結尾
\Z 輸入的結尾,僅用於最後的結束符(如果有的話)
\z 輸入的結尾

Greedy 數量詞
X? X,一次或一次也沒有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n
X{n,} X,至少 n
X{n,m} X,至少 n 次,但是不超過m

Logical 運算子
XY X 後跟 Y
X|Y XY
(X) X,作為擷取的群組

Back 引用
\n 任何匹配的 nth擷取的群組

<span style="white-space:pre"></span>public static void check() {<span style="white-space:pre"></span>String string = "aoooooz";<span style="white-space:pre"></span>String regex = "ao{4,}z";//Regex<span style="white-space:pre"></span>boolean flag = string.matches(regex);<span style="white-space:pre"></span>System.out.println(string+" : "+flag);<span style="white-space:pre"></span>}

常見功能

1.匹配 2.切割 3.替換 4.擷取

匹配:用的是String類中的matches方法

public static void check() {//匹配手機號碼是否正確String tel = "18753377511";//第一位是1,第二位是3或5或8//String regex = "1[358][0-9]{9}";String regex = "1[358]\\d{9}";//字串中\,代錶轉義,所以再加上一個"\"將"\"轉義boolean flag = tel.matches(regex);System.out.println(tel+" : "+flag);}


切割:就是以前用的String類中的split(String regex)方法,以前用的是" ",空格一般的非特殊符號,都可看作規則

空格

public static void check() {//以空格為分割,切割,空格可能出現多次String str = "a   b  c     d e f";String regex = " +";//空格出現1次或者多次String[] line = str.split(regex);for(String i : line){System.out.println(i);}}
點,PS:點本身在Regex中是特殊符合
String str = "a.b.c.d.e..f";String regex = "\\.+";//\.轉義後還是.,所以再加一個\String[] line = str.split(regex);

以疊詞為分割

正則用()來封裝成組

所以疊詞就可以表示為,.代表任一字元,(.)封裝成組,(.)\\1,代表餘下都和第一組相同

String str = "a@@@b####c...dtttef";String regex = "(.)\\1+";//String[] line = str.split(regex);

組:((A)(B(C))),共有幾組,哪幾組

以左括弧數,

((A)(B(C))) 1

(A)    2

(B(C))     3

(C)         4

無括弧就是第0組


替換:

replaceAll(String regex,String replacement)
使用給定的 replacement 替換此字串所有匹配給定的Regex的子字串。

replaceFirst(String regex,String replacement)
使用給定的 replacement 替換此字串匹配給定的Regex的第一個子字串。

public static void check() {//把疊詞變為一個字元String str = "abgggggcffffdggggs";String regex = "(.)\\1+";//str = str.replaceAll(regex, "$1");System.out.println(str);}

PS:貨幣符號在其他參數中,可以對前一個參數中的已有的正則規則的擷取

public static void check() {//18753377511 -> 187****7511String str = "18753377511";String regex = "(\\d{3})\\d{4}(\\d{4})";System.out.println(str);str = str.replaceAll(regex, "$1****$2");System.out.println(str);}

擷取

正則本身就是一個對象

Pattern類

指定為字串的Regex必須首先被編譯為此類的執行個體。然後,可將得到的模式用於建立Matcher 對象,依照Regex,該對象可以與任意字元序列匹配。執行匹配所涉及的所有狀態都駐留在匹配器中,所以多個匹配器可以共用同一模式。

//將正則的規則進行對象的封裝
//Pattern p = Pattern.compile("a*b");
//通過正則對象的matcher方法字串相關聯,擷取對字串操作的匹配器對象Matcer
//Matcher m = p.matcher("aaaab");
//通過Matcher匹配器對象的方法對字串進行操作
//boolean b = m.matches();

Matcher類

  • matches 方法嘗試將整個輸入序列與該模式比對。

  • lookingAt 嘗試將輸入序列從頭開始與該模式比對。

  • find 方法掃描輸入序列以尋找與該模式比對的下一個子序列。

public static void check() {String str = "ni hao,wohao,ta ye hao";String regex = "\\b[a-z]{3}\\b";//\\b :單詞邊界Pattern p = Pattern.compile(regex);Matcher m = p.matcher(str);while(m.find())//想要擷取,就要先找,有沒有,有才能擷取{System.out.println(m.group());System.out.println(m.start()+" : "+m.end());//擷取起始下標}}

練習:

將aaa...aa..aaa...bbb...b...bbb...ccc...ccc 變為 abcd

public static void test() {String str = "aaa...aa..aaa...bbb...b...bbb...ccc...ccc";System.out.println(str);String regex = "\\.+";str = str.replaceAll(regex, "");//去點regex = "(.)\\1+";str = str.replaceAll(regex, "$1");//去疊詞System.out.println(str);}
排序IP地址

public static void test() {//String str = "192.0.0.1    127.0.0.24  3.3.3.5    150.15.3.41";//System.out.println("ip : "+str);//String regex = " +";//String[] strs = str.split(regex);////TreeSet<String> ts = new TreeSet<String>();//自動排序//for(String s : strs){//ts.add(s);//}//for(String s : ts){//這樣排,是按照字串排序//System.out.println(s);//}//所以在每個ip的每段數字,就用兩個0補全String str = "192.0.0.1    127.0.0.24  3.3.3.5    150.15.3.41";String regex = "(\\d+)";str = str.replaceAll(regex, "00$1");System.out.println("補0 : "+str);regex = "0*(\\d{3})";str = str.replaceAll(regex, "$1");System.out.println("保留3位 : "+str);regex = " +";String[] strs = str.split(regex);TreeSet<String> ts = new TreeSet<String>();//自動排序for(String s : strs){ts.add(s);}for(String s : ts){System.out.println(s.replaceAll("0*(\\d+)", "$1"));}}

郵箱地址的簡單校正

public static void test() {String mail = "aa_a@163.com.cn";String regex = "\\w+@\\w+(\\.[a-zA-Z]{2,3})+";//+代表一次或多次boolean flag = mail.matches(regex);System.out.println(mail+" : "+flag);}

注意:開發時,正則閱讀性差,會不斷驗證,然後封裝起來


練習:網頁爬蟲:一個程式用於在互連網中擷取符合指定規則的資料

爬取郵箱地址。

public class asd {public static void main(String[] args) throws Exception {//List<String> list = getmail();//本地List<String> list =  getweb();//網路for(String i : list){System.out.println(i);}}public static List<String> getweb() throws Exception{//URL url = new URL("http://192.168.0.1:8080/myweb/mymail.html");URL url = new URL("http://news.baidu.com/");BufferedReader brin = new BufferedReader(new InputStreamReader(url.openStream()));String mail_regex = "\\w+@\\w+(\\.\\w+)+";Pattern p = Pattern.compile(mail_regex);List<String> list = new ArrayList<String>();String line = null;while((line = brin.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){list.add(m.group());}}return list;}public static List<String> getmail() throws Exception {//1.讀取源檔案BufferedReader br = new BufferedReader(new FileReader("g:\\mymail.html"));String mail_regex = "\\w+@\\w+(\\.\\w)+";Pattern p = Pattern.compile(mail_regex);List<String> list = new ArrayList<String>();String line = null;//2.對讀取的資料進行規則的匹配,從中擷取符合規則的資料while((line = br.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){//3.將符合規則的資料存放區到集合list.add(m.group());}}return list;}}





JAVARegex學習

Regex和java無關
相關知識你可以看看javaAPI中的Regex 也可以看看JQuery中的Regex

運算式全集
字元 描述
\ 將下一個字元標記為一個特殊字元、或一個原義字元、或一個反向參考、或一個八進位轉義符。例如,“n”匹配字元“n”。“\n”匹配一個分行符號。串列“\\”匹配“\”而“\(”則匹配“(”。
^ 匹配輸入字串的開始位置。如果設定了RegExp對象的Multiline屬性,^也匹配“\n”或“\r”之後的位置。
$ 匹配輸入字串的結束位置。如果設定了RegExp對象的Multiline屬性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子運算式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等價於{0,}。
+ 匹配前面的子運算式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等價於{1,}。
? 匹配前面的子運算式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等價於{0,1}。
{n} n是一個非負整數。匹配確定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的兩個o。
{n,} n是一個非負整數。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等價於“o+”。“o{0,}”則等價於“o*”。
{n,m} m和n均為非負整數,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”將匹配“fooooood”中的前三個o。“o{0,1}”等價於“o?”。請注意在逗號和兩個數之間不能有空格。
? 當該字元緊跟在任何一個其他限制符(*,+,?,{n},{n,},{n,m})後面時,匹配模式是非貪婪的。非貪婪模式儘可能少的匹配所搜尋的字串,而預設的貪婪模式則儘可能多的匹配所搜尋的字串。例如,對於字串“oooo”,“o+?”將匹配單個“o”,而“o+”將匹配所有“o”。
. 匹配除“\n”之外的任何單個字元。要匹配包括“\n”在內的任何字元,請使用像“(.|\n)”的模式。
(pattern) 匹配pattern並擷取這一匹配。所擷取的匹配可以從產生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中則使用$0…$9屬性。要匹配圓括弧字元,請使用“\(”或“\)”。
(?:pattern) 匹配pattern但不擷取匹配結果,也就是說這是一個非擷取匹配,不進行儲存供以後使用。這在使用或字元“(|)”來組合一個模式的各個部分是很有用。例如“industr(?:y|ies)”就是一個比“industry|industries”更簡略的運算式。
(?=pattern) 正向肯定預查,在任何匹配pattern的字串開始處匹配尋找字串。這是一個非擷取匹配,也就是說,該匹配不需要擷取供以後使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。預查不消耗字元,也就是說,在一個匹配發生後,在最後一次匹配之後立即開始下一次匹配的搜尋,而不是從包含預查的字元之後開始。
(?!pattern) 正向否定預查,在任何......餘下全文>>
 
javaRegex

^ 和 $ 他們是分別用來匹配字串的開始和結束,以下分別舉例說明:

"^The": 開頭一定要有"The"字串;

"of despair$": 結尾一定要有"of despair" 的字串;

那麼,

"^abc$": 就是要求以abc開頭和以abc結尾的字串,實際上是只有abc匹配。

"notice": 匹配包含notice的字串。

你可以看見如果你沒有用我們提到的兩個字元(最後一個例子),就是說 模式(Regex) 可以出現在被檢驗字串的任何地方,你沒有把他鎖定到兩邊。

接著,說說 '*', '+',和 '?',

他們用來表示一個字元可以出現的次數或者順序. 他們分別表示:

"zero or more"相當於{0,},
"one or more"相當於{1,},
"zero or one."相當於{0,1}, 這裡是一些例子:
"ab*": 和ab{0,}同義,匹配以a開頭,後面可以接0個或者N個b組成的字串("a", "ab", "abbb", 等);
"ab+": 和ab{1,}同義,同上條一樣,但最少要有一個b存在 ("ab", "abbb", 等.);
"ab?":和ab{0,1}同義,可以沒有或者只有一個b;
"a?b+$": 匹配以一個或者0個a再加上一個以上的b結尾的字串.
要點, '*', '+',和 '?'只管它前面那個字元.

你也可以在大括弧裡面限制字元出現的個數,比如

"ab{2}": 要求a後面一定要跟兩個b(一個也不能少)("abb");
"ab{2,}": 要求a後面一定要有兩個或者兩個以上b(如"abb", "abbbb", 等.);
"ab{3,5}": 要求a後面可以有2-5個b("abbb", "abbbb", or "abbbbb").
現在我們把一定幾個字元放到小括弧裡,比如:

"a(bc)*": 匹配 a 後面跟0個或者一個"bc";
"a(bc){1,5}": 一個到5個 "bc."
還有一個字元 '│', 相當於OR 操作:

"hi│hello": 匹配含有"hi" 或者 "hello" 的 字串;

"(b│cd)ef": 匹配含有 "bef......餘下全文>>
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.