摘要:正則表達(dá)式等待匹配的字符這里可以輸入任何繼承了的類返回一個(gè)值說(shuō)明是否匹配這里需要注意的是,和均不允許通過(guò)構(gòu)造器新建一個(gè)對(duì)象。
前言
之前一直想要做一個(gè)自己的爬蟲,然后從nba數(shù)據(jù)相關(guān)的網(wǎng)上【虎撲,騰訊,官網(wǎng)等,要視網(wǎng)站是否支持】爬點(diǎn)數(shù)據(jù)寫數(shù)據(jù)分析和圖形化展示。雖然年輕的時(shí)候就實(shí)現(xiàn)過(guò)這個(gè)功能,但是當(dāng)時(shí)直接借用了一個(gè)網(wǎng)上現(xiàn)成的jar包,然后在那個(gè)基礎(chǔ)上寫了一個(gè)非常簡(jiǎn)陋的正則表達(dá)式來(lái)提取數(shù)據(jù)。這次打算自己用JAVA API寫一個(gè)爬蟲,里面除了能讀取HTML或是JSON或是XML,還要能夠相應(yīng)的支持多線程【這個(gè)功能將最后完成】。
今天這篇博客重點(diǎn)講解java中和正則表達(dá)式相關(guān)的API為后序程序的實(shí)現(xiàn)做一個(gè)鋪墊。后序的實(shí)現(xiàn)將在未來(lái)的博客3或4或5中展示,也會(huì)提供github源碼來(lái)供大家參考和指教。所以也歡迎大家關(guān)注我,以便獲得后序的更新。
關(guān)于正則表達(dá)式的基本知識(shí)請(qǐng)參考我的博客正則表達(dá)式 深入淺出1--你的符號(hào)我做主【持續(xù)更新中
在這里,我需要再補(bǔ)充一些博客1中沒(méi)有提及但是必須了解的知識(shí)。(完整的正則表達(dá)式構(gòu)造子列表請(qǐng)參考JAVA的API,在文章最后有給出傳送門)
在博客1中,我將最常用的一些符號(hào)整理出來(lái),這里再說(shuō)一些還需要了解的符號(hào)。
字符
xhh 十六進(jìn)制值為0xhh的字符
uhhhh 十六進(jìn)制表示為oxhhhh的Unicode字符
字符類
[abc[def]] 相當(dāng)于合并操作 等價(jià)于[abcdef]
[a-z&&[hij]] 相當(dāng)于交集操作,等價(jià)于[hij]
[a-z&&[^b-d]] 相當(dāng)于減操作 等價(jià)于[ae-z]
邊界匹配符
詞的邊界,詞的邊界是指w和W之間的位置,它是一個(gè)定位符,并不代表任何具體的字符
B 非詞的邊界,也就是是w和w 以及W和W之間的位置
這里新添的兩個(gè)定界符有點(diǎn)難理解。我們已知w是指詞字符[a-zA-Z0-9],而W是指[^a-zA-Z0-9]。這里舉個(gè)例子來(lái)說(shuō)明b和B都匹配了什么。
假設(shè)我們待匹配的字符串為"hello world!
"
如果調(diào)用方法String[] result = s.split("");
那么我們會(huì)發(fā)現(xiàn)輸出為["hello", "world", " ", "! rn"],也就是說(shuō)我們可以將字符串看成是"_hello_ _world_!
"其中_代表單詞分界處。
那么如果_代表非單詞分界處,那么上述句子可以表示成"h_e_l_l_o w_o_r_l_d!_
_
"
那么,在大多數(shù)情況下,我們都會(huì)通過(guò)詞的邊界符來(lái)實(shí)現(xiàn)獲取而不是進(jìn)行判斷。
量詞量詞描述了一個(gè)模式吸收輸入文本的方式。量詞總共分為三種,貪婪型、勉強(qiáng)型和占有型。下面分別介紹這三種量詞以便更好的構(gòu)建正則表達(dá)式。
貪婪型
貪婪型模式下的正則表達(dá)式會(huì)發(fā)現(xiàn)盡可能多的匹配。也就是說(shuō),即便當(dāng)前情況已經(jīng)滿足了匹配,貪婪模式還是會(huì)繼續(xù)測(cè)試下一個(gè)字符直至匹配失敗為止。一旦匹配失敗,就開(kāi)始回退直至找到合適的匹配。
在默認(rèn)情況下的一般正則表達(dá)式都是貪婪型的。
勉強(qiáng)型
在希望勉強(qiáng)匹配的正則表達(dá)式后面加?號(hào)即可進(jìn)行勉強(qiáng)匹配。勉強(qiáng)匹配是指這個(gè)量詞滿足模式所需要的最小字符數(shù)就立刻停止。
占有型
目前,這種類型的量詞只在JAVA中才可以用。占有型不同于前面兩者,它不會(huì)進(jìn)行回溯。我們知道一個(gè)正則表達(dá)式對(duì)應(yīng)的字符串可能有多種。在貪婪型中,如果下一個(gè)匹配失敗,則放出已占有字符回溯到上一個(gè)滿足的情形繼續(xù)判斷。而勉強(qiáng)型則是多占有一個(gè)字符繼續(xù)判斷。占有型則不保存這些中間結(jié)果。一旦占有則不會(huì)釋放。
下面舉一個(gè)例子來(lái)說(shuō)明這些情況:
輸入的字符串: 在Java中,和正則表達(dá)式最息息相關(guān)的兩個(gè)類就是Pattern和Matcher了。基本上所有正則表達(dá)式的底層實(shí)現(xiàn)都是通過(guò)Pattern和Matcher來(lái)實(shí)現(xiàn)的。比如說(shuō),我們非常了解的String中的matches方法,實(shí)際上也是通過(guò)Pattern和Matcher的配合來(lái)實(shí)現(xiàn)的。 創(chuàng)建正則表達(dá)式并判斷字符流是否符合。 這里需要注意的是,Pattern和Matcher均不允許通過(guò)構(gòu)造器新建一個(gè)對(duì)象。不僅如此,Pattern類是相對(duì)而言線程安全的,而Matcher類不是如此。 構(gòu)造器 第二個(gè)構(gòu)造pattern的方法中多了一個(gè)flag參數(shù),這個(gè)參數(shù)允許我們定義pattern的模式,這里講幾個(gè)比較重要的模式: Pattern.CASE_INSENSITIVE: 等價(jià)于正則表達(dá)式中的?i,是的匹配可以大小寫不敏感 如果希望有多個(gè)Pattern,可以輸入Pattern.compile("正則表達(dá)式", Pattern1 | Pattern2 | Pattern3) 分割 分組 查找 舉個(gè)栗子 替換 這里講一下appendReplacement和appendTail方法。appendReplacement允許開(kāi)發(fā)者在替換的過(guò)程中針對(duì)將被替換的內(nèi)容進(jìn)行一些動(dòng)態(tài)的操作。這個(gè)方法將逐步推進(jìn)的向前替換,并將替換的結(jié)果添加到輸入的s中。除此以外,對(duì)于沒(méi)有被掃描到的部分,可以通過(guò)appendTail方法添加到輸入的s中。 例子: 輸出為: 其實(shí)正則表達(dá)式的適用范圍非常廣,除了和CharSequence配合使用之外,還可以和JAVA I/O如Scanner類,InputReader類等聯(lián)合使用。核心還是在于Pattern類和Matcher類的組合使用。 JAVA API 文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。 轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70212.html 摘要:探索專為而設(shè)計(jì)的將探討進(jìn)行了何種改進(jìn),以及這些改進(jìn)背后的原因。關(guān)于最友好的文章進(jìn)階前言之前就寫過(guò)一篇關(guān)于最友好的文章反響很不錯(cuò),由于那篇文章的定位就是簡(jiǎn)單友好,因此盡可能的摒棄復(fù)雜的概念,只抓住關(guān)鍵的東西來(lái)講,以保證大家都能看懂。
周月切換日歷
一個(gè)可以進(jìn)行周月切換的日歷,左右滑動(dòng)的切換月份,上下滑動(dòng)可以進(jìn)行周,月不同的視圖切換,可以進(jìn)行事件的標(biāo)記,以及節(jié)假日的顯示,功能豐富
Andr... 摘要:它包括兩個(gè)類和一個(gè)是一個(gè)正則表達(dá)式經(jīng)編譯后的表現(xiàn)模式。這個(gè)標(biāo)志能讓表達(dá)式忽略大小寫進(jìn)行匹配。默認(rèn)情況下,這兩個(gè)表達(dá)式僅僅匹配字符串的開(kāi)始和結(jié)束。返回當(dāng)前查找而獲得的與指定的組匹配的子串內(nèi)容
Pattern和MatcherJava.util.regex 是一個(gè)用正則表達(dá)式所訂制的模式來(lái)對(duì)字符串進(jìn)行匹配工作的類庫(kù)包。它包括兩個(gè)類:Pattern和MatcherPattern: 一個(gè)Patt... 摘要:直接使用正則表達(dá)式對(duì)輸入的字符串進(jìn)行匹配,匹配成功則返回使用正則表示式,進(jìn)行字符串分割進(jìn)行匹配操作,如果匹配成功,這三個(gè)方法都會(huì)返回其中,是在源字符串中找出和正則表達(dá)式匹配的字符串。
概念
正則表達(dá)式
在閱讀本文前,你應(yīng)該已經(jīng)了解了正則表達(dá)式的基本概念以及如何書寫正則表達(dá)式。如果對(duì)正則表達(dá)式不是太了解,或者想更深入地了解正則表示式,請(qǐng)點(diǎn)擊這里。
捕獲組
捕獲組能夠讓我們方便地從正則表達(dá)... 摘要:大多數(shù)待遇豐厚的開(kāi)發(fā)職位都要求開(kāi)發(fā)者精通多線程技術(shù)并且有豐富的程序開(kāi)發(fā)調(diào)試優(yōu)化經(jīng)驗(yàn),所以線程相關(guān)的問(wèn)題在面試中經(jīng)常會(huì)被提到。將對(duì)象編碼為字節(jié)流稱之為序列化,反之將字節(jié)流重建成對(duì)象稱之為反序列化。
JVM 內(nèi)存溢出實(shí)例 - 實(shí)戰(zhàn) JVM(二)
介紹 JVM 內(nèi)存溢出產(chǎn)生情況分析
Java - 注解詳解
詳細(xì)介紹 Java 注解的使用,有利于學(xué)習(xí)編譯時(shí)注解
Java 程序員快速上手 Kot... 閱讀 1207·2021-09-03 10:44 閱讀 603·2019-08-30 13:13 閱讀 2796·2019-08-30 13:11 閱讀 1967·2019-08-30 12:59 閱讀 1034·2019-08-29 15:32 閱讀 1595·2019-08-29 15:25 閱讀 987·2019-08-29 12:24 閱讀 1277·2019-08-27 10:58info
貪婪模式正則表達(dá)式:<.*>
返回輸出:info
勉強(qiáng)模式正則表達(dá)式:<.*?>
返回輸出:
占有模式正則表達(dá)式:<.*+>
返回輸出:info
Pattern和Matcher API
在這篇博客中,我將介紹重點(diǎn)的API,詳細(xì)的信息請(qǐng)各位自行參考JAVA DOC。 Pattern pattern = Pattern.compile("正則表達(dá)式");
Matcher matcher = pattern.matcher("等待匹配的字符");//這里可以輸入任何繼承了CharSequence的類
matcher.matches();//返回一個(gè)boolean值說(shuō)明是否匹配
static Pattern compile(String regex)
static Pattern compile(String regex, int flag);
Pattern.COMMENTS : 等價(jià)于正則表達(dá)式中的?x,會(huì)忽略空格符和以#開(kāi)頭到行末的注釋
Pattern.MULTILINE : 等價(jià)于?m,使得^和&符號(hào)可以匹配一行的始末,而不僅僅是整個(gè)字符串的始末
Pattern自己也定義了split方法。它會(huì)根據(jù)之前compile的正則表達(dá)式進(jìn)行分割并返回String[],limit值是指分割出的String[]的size不會(huì)超過(guò)這個(gè)limit值。String[] split(CharSequences c, int limit)
String[] split(CharSequences c)
在這里還需要在講解一個(gè)分組的概念以便為后面做鋪墊。正則表達(dá)式的分組是指將一對(duì)括號(hào)中的表達(dá)式劃為一個(gè)分組。因此形如A(B(CD)(E))的正則表達(dá)式一共有四個(gè)分組{A(B(CD)(E)),B(CD)(E),(CD),(E)},其中第0個(gè)分組默認(rèn)為完整的正則表達(dá)式。 int groupCount() //返回除了第0組的總分組數(shù)
boolean find() //從當(dāng)前下標(biāo)開(kāi)始匹配,如果存在滿足正則表達(dá)式的值,則返回true
boolean find(int i)//從下標(biāo)i開(kāi)始匹配,如果存在滿足正則表達(dá)式的值,返回true
String group() //返回前一次匹配的第0個(gè)分組的內(nèi)容
String group(int i)//返回前一次匹配的第i個(gè)分組的內(nèi)容
int start() //返回上一次匹配成功的內(nèi)容的起始下標(biāo)
int end() //返回上一次匹配成功的內(nèi)容的終止下標(biāo)+1
Pattern p = Pattern.compile("<.*?>");
Matcher matcher = p.matcher("
data ");
while(matcher.find()){
System.out.println(matcher.group());
//先后輸出
} void replaceFirst(String replacement);
void replaceAll(String replacement);
void appendReplacement(StringBuffer s, String replacement);
void appendTail(StringBuffer s);
Pattern p = Pattern.compile("hello", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("hello world one hello world 2");
StringBuffer s = new StringBuffer();
while(m.find()){
m.appendReplacement(s, m.group().toUpperCase());
System.out.println(s);
}
m.appendTail(s);
System.out.println(s);
相關(guān)文章
Java進(jìn)階之路
Java深入 - Java的正則表達(dá)式 Pattern和Matcher
java正則表式的使用
Java開(kāi)發(fā)
發(fā)表評(píng)論
0條評(píng)論
andycall
男|高級(jí)講師
TA的文章
閱讀更多
通配符證書有什么好處?常用通配符SSL證書有哪些?
我所知道的flex布局 —— 上篇
如何造一個(gè)移動(dòng)端的聯(lián)動(dòng)選擇器(一)
CSS魔法堂:你真的理解z-index嗎?
前端每日實(shí)戰(zhàn):32# 視頻演示如何用純 CSS 創(chuàng)作六邊形按鈕特效
CSS3 border-radius妙用
Vue 實(shí)用分頁(yè)組件paging(頁(yè)數(shù)太多時(shí)顯示省略號(hào))
Go 語(yǔ)言 Excel 類庫(kù) Excelize 2.0.0 版本發(fā)布