Java与正则表达式
Java與正則表達(dá)式
標(biāo)簽: Java基礎(chǔ)
正則
正如正則的名字所顯示的是描述了一個規(guī)則, 通過這個規(guī)則去匹配字符串. 學(xué)習(xí)正則就是學(xué)習(xí)正則表達(dá)式的語法規(guī)則
正則語法
普通字符
字母, 數(shù)字, 漢字, 下劃線, 以及沒有特殊定義的標(biāo)點(diǎn)符號都是普通字符. 表達(dá)式中的普通字符在匹配一個字符串時, 匹配與之相同的一個字符.
轉(zhuǎn)義字符
| \n | 換行符 |
| \t | 制表符 |
| \^ \$ \( \) \{ \} \? \+ \* | \\ \[ \] | 匹配這些字符本身 |
標(biāo)準(zhǔn)字符集合
| \d | 任意一個數(shù)字 |
| \w | 任意一個字母/數(shù)字/下劃線 |
| \s | 任意一個空格/制表符/換行符等空白字符 |
| . | 小數(shù)點(diǎn)在內(nèi)的任意一個字符(除\n外) |
| [\s\S] | 匹配\n在內(nèi)的任意一個字符 |
- 注意大小寫: 大寫是取反
自定義字符集合
[] 方括號匹配方式, 能夠匹配方括號中的任意一個字符.
| [ab5@v] | 匹配a b 5 @ v中任意一個 |
| [^ab5@v] | 匹配a b 5 @ v之外任意一個 |
| [f-k] | 匹配f-k之間任意一個字母 |
| [^f-k] | 匹配f-k之外任意一個 |
| [f-k0-3] | 匹配f-k或0-3之間任意一個字母 |
| [^f-k0-3] | 不匹配f-k或0-3之間任意一個字母 |
注:
- 正則表達(dá)式中的特殊符號, 被包含到[]中, 則失去特殊意義, 除了- ^之外.
- []中的^表示取反的含義.
- []中的-表示范圍的含義
- 標(biāo)準(zhǔn)字符集合(除小數(shù)點(diǎn)外),如果被包含于中括號中,則自定義集合將包含該集合.
如[\d.\-+]將匹配: 數(shù)字, 小數(shù)點(diǎn), -, +
量詞
| {n} | 表達(dá)式重復(fù)n次 |
| {m,n} | 表達(dá)式至少重復(fù)m次,最多重復(fù)n次 |
| {m,} | 表達(dá)式至少重復(fù)m次 |
| ? | 匹配表達(dá)式0次或者1次 |
| + | 表達(dá)式至少出現(xiàn)1次,相當(dāng)于 {1,} |
| * | 表達(dá)式不出現(xiàn)或出現(xiàn)任意次,相當(dāng)于 {0,} |
貪婪模式與非貪婪模式
貪婪模式: 匹配字符越多越好, 默認(rèn).
非貪婪模式: 匹配字符越少越好, 需要在量詞后再加上一個?號.示例
- 匹配手機(jī)號1[358]\d{9}
- 匹配郵箱 ([\w\-\.]+)@([0-9a-zA-Z\-]+)(\.[a-zA-Z]{2,4}){1,2}
字符邊界
零寬匹配: 匹配的不是字符而是位置(符合某種條件的位置),不匹配任何字符.
| ^ | 與字符串開始的地方匹配 |
| $ | 與字符串結(jié)束的地方匹配 |
| \b | 匹配一個單詞邊界,也就是單詞和空格之間的位置 |
注: \b會匹配這樣一個位置: 前面的字符與后面的字符不全是\w
選擇符與分組
| | | 左右兩邊表達(dá)式之間 “或” 關(guān)系,匹配左邊或右邊 |
| () 捕獲組 | 被修飾時,()中的表達(dá)式可以作為整體被修飾; 取匹配結(jié)果時, ()中的表達(dá)式匹配到的內(nèi)容可以被單獨(dú)得到; 每一對括號會被分配一個編號(以(為準(zhǔn),從左到右: 從1開始) |
| (?:exp) 非捕獲組 | 一些表達(dá)式中, 不得不使用(), 但又不需保存()中子表達(dá)式匹配的內(nèi)容, 這時可以使用非捕獲組來抵消()帶來的副作用 |
注: 非捕獲組可以用于當(dāng)處理大量文本時用于優(yōu)化內(nèi)存分配.
- 反引用\nnn
由上面可知, 捕獲組默認(rèn)被分配了編號, 通過反向引用, 可以對分組已捕獲的字符串進(jìn)行引用 - 示例
(\w{2})\1 匹配類似toto dodo gogo這樣由一個單詞復(fù)制而來得到的字符串
(img)\w+\1 匹配前后都是img的字符串
零寬斷言(預(yù)搜索)
- 零寬度: 只進(jìn)行子表達(dá)式的匹配, 匹配內(nèi)容不計入最終的匹配結(jié)果.
- 位置匹配: 判斷當(dāng)前位置的前后字符是否符合指定的條件, 但不保留前后的字符.
正則表達(dá)式中, 如果子表達(dá)式匹配到得是字符內(nèi)容, 而非位置, 并被保留到最終的匹配結(jié)果中, 那么就認(rèn)為這個子表達(dá)式是占有字符的; 如果子表達(dá)式匹配的僅僅是位置, 或者匹配的內(nèi)容并不保存到最終的匹配結(jié)果中, 那么就認(rèn)為這個子表達(dá)式是零寬度的(占有字符或零寬度, 是針對匹配的內(nèi)容是否保留到最終結(jié)果而言的)
| (?=exp) | 斷言自身出現(xiàn)的位置的后面能夠匹配表達(dá)式exp |
| (?!exp) | 斷言自身出現(xiàn)的位置的后面不能匹配表達(dá)式exp |
| (?<=exp) | 斷言自身出現(xiàn)的位置的前面能夠匹配表達(dá)式exp |
| (?<\!exp) | 斷言自身出現(xiàn)的位置的前面不能匹配表達(dá)式exp |
- 示例
[a-z]+(?=ing) 匹配所有以ing結(jié)尾的單詞, 但ing并不放入字符串
[a-z]+(?=\d+) 匹配所有以數(shù)字結(jié)尾的單詞
[a-z]+(?!\d+) 匹配不以數(shù)字結(jié)尾的單詞
(?<=(href=\")) 匹配以href="開頭的字符串
Java Pattern與Matcher
- java.util.regex包下提供的Pattern與Matcher兩個類提供了在Java中的正則支持;
- Pattern對象是正則表達(dá)式編譯后在內(nèi)存中的表現(xiàn)形式, 因此, 正則表達(dá)式字符串必須先被編譯為Pattern對象Pattern pattern = Pattern.compile("\\w+");然后再利用該P(yáng)attern對象創(chuàng)建對象的Matcher對象Matcher matcher = pattern.matcher(input);.
- Matcher對象是一個對CharSequence執(zhí)行匹配操作的正則引擎: 執(zhí)行匹配所涉及的狀態(tài)保留在Matcher對象中, 多個Matcher對象可共享同一個Pattern對象.
由上例可以看到: 其實String中某些方法也支持正則表達(dá)式, 如split, replace等(Pattern,Matcher與String的其他用法請參考JDK文檔).
小實驗-抓取網(wǎng)頁中所有的超鏈接
/*** 模仿網(wǎng)絡(luò)爬蟲, 抓取網(wǎng)站html, 將里面所有的超鏈接都分析出來* Created by jifang on 15/12/15.*/ public class HtmlAnalyzer {private final String FILE_PATH = "/Users/jifang/save.txt";@Testpublic void client() throws IOException {String html = downloadHtml("http://www.163.com/", "gbk");// (?<=(href=\"))(?:[\w.\/\:\?\=\&]+)(?=\") 匹配url的正則Set<String> urlSet = analyzeHtml(html, "(?<=(href=\\\"))(?:[\\w.\\/\\:\\?\\=\\&]+)(?=\\\")");saveToFile(urlSet);System.out.println();}private String downloadHtml(String url, String charset) throws IOException {URL readUrl = new URL(url);BufferedReader reader = new BufferedReader(new InputStreamReader(readUrl.openStream(), charset));return CharStreams.toString(reader);}private Set<String> analyzeHtml(String html, String regex) {Set<String> urlSet = new HashSet<>();// 匹配url的正則表達(dá)式Matcher matcher = Pattern.compile(regex).matcher(html);while (matcher.find()) {String group = matcher.group();urlSet.add(group);}return urlSet;}private void saveToFile(Set<String> urlSet) throws IOException {PrintStream printer = new PrintStream(new FileOutputStream(FILE_PATH));for (String url : urlSet) {printer.println(url);}printer.flush();printer.close();} }- 附- 運(yùn)行上程序需要在pom.xml中添加以下依賴
推薦幾個正則驗證工具:
- Mac端: RegExRX
- Win端: RegexBuddy
- Web端: 在線正則表達(dá)式測試
參考
- 揭開正則表達(dá)式的神秘面紗
- Java正則表達(dá)式教程
總結(jié)
以上是生活随笔為你收集整理的Java与正则表达式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql主从日志的定期清理
- 下一篇: Mac配置炫酷终端以及直接预览Markd