正則表達式
正則表達式的用途:文本的複雜處理
開發中使用正則表達式的流程:
- 分析所要匹配的數據,寫出測試用的典型數據
- 在工具軟件中進行匹配測試
- 在程序中調用通過的正則表達式
正則表達式語法
普通字符:
字母,數字,漢字,下劃線,以及沒有特殊定義的標點符號。表達式中的普通字符在匹配一個字符串時匹配與之相同的一個字符。
簡單的轉義字符
\n -->換行符,\t -->製表符 \ -->代表\本身 ^,$,(,)等匹配這些字符本身。
標準字符集合
能和多種字符匹配的表達式
注意區分大小寫,大寫是相反的意思
- \d —> 0-9中任意一個數字
- \w —>任意一個字母或數字或下劃線,即0-9,a-z,A-Z,_中任意一個
- \s —>包括空格,製表符,換行符等空白字符的其中任意一個
- . —> 小數點可以匹配任意一個字符(除換行符)
自定義字符集合
-
[] 方括號匹配方式,能夠匹配方括號中任意一個字符
-
正則表達式中的特殊符號,被包含到中括號中,則失去了特殊含義,除了^,-之外 標準字符集合,除了小數點外,如果被包含於中括號,自定義符號集合將包含該集合: [\d.-+]將匹配數字,小數點,+,-
1 [abc@] --> 匹配"a"或"b"或"c"或"@“中任意一個
2 [ ^abc] --> 匹配"a”,“b”,“c"之外的任意一個字符
3 [f-k] -->匹配"f"到"k"之間的任意一個字母
4 [ ^A-F0-3] -->匹配"A"到"F”,"0"到"3"之外的任意一個字符
量詞:修飾匹配次數的特殊符號
- {n} -->表示表達式重複n次 ,{m,n}–>表示至少重複m次,至多重複n次 ,{m,} -->表示至 少重複m次。
- ? --> 匹配表達式0次或1次 ;+ --> 表達式至少出現一次 ;* --> 表達式不出現或出現任意次。
- 匹配次數中的貪婪模式(匹配字符越多越好,默認)。
- 匹配次數的非貪婪模式(匹配字符越少越好,修飾匹配次數的特殊符號後再加上一個?號)。
字符邊界
- 本組標記匹配的不是字符而是位置,符合某種條件的位置。
- ^ 表示與字符串開始的地方匹配。
- $表示與字符串結束的地方匹配。
- \b匹配一個單詞的邊界(前面的字符和後面的字符不全是\w)。
正則表達式的匹配模式
-IGNORECASE 忽略大小寫模式:默認情況下正則表達式區分大小寫
-SINGLELINE單行模式:整個文本看作一個字符串,只有一個開頭,一個結尾。使.可以匹配包含換行符在內的任意字符
-MULTILINE 多行模式:每行都是一個字符串,都有開頭和結尾。\A -->開始字符,\Z–>結束字符
選擇符和分組
-
| 分支結構:左右兩邊表達式之間或關係,匹配左邊或右邊。
-
() 捕獲組:
1 在被匹配次數的時候,括號中的表達式可以作爲整體被修飾。
2 去匹配結果的時候,括號中的表達式匹配到的內容可以被單獨得到。
3 每一對括號會分配一個編號,使用()的捕獲根據左括號的順序從1開始自動編號。捕獲元素編號爲零的第一個捕獲是由整個正則表達式模式匹配的文本 -
(?:Expression) 非捕獲組: 一些表達式中不得不用(),但又不需要保存()中子表達式匹配的內容,這時候可以用非捕獲組來抵消使用()帶來的副作用
反向引用 (\nnn)
- 每一對()會分配一個編號,使用()的捕獲根據左括號的順序從1開始自動編號。
- 通過反向引用,可以對分組已捕獲的字符串進行引用。
預搜索(零寬斷言)
- 只進行子表達式的匹配,匹配內容不計入最終的匹配結果,是零寬度
- 這個位置應該符合某個條件。判斷當前位置的前後字符,是否符合指定的條件,但不匹配前後的字符。是對位置的匹配。
- 正則表達式匹配過程中,如果子表達式匹配到的是字符內容,而非位置,並被保存在最終的匹配結果中,那麼就認爲這個子表達式是佔有字符的;反之則認爲這個子表達式是零寬度的。佔有字符還是零寬度,是針對匹配的內容是否保存到最終的匹配結果中而言的。
(?=exp) :斷言自身出現的位置的後面可以匹配表達式exp
(?<=exp) :斷言自身出現的位置的前面可以匹配表達式exp
(?!exp) :斷言自身出現的位置的後面不可以匹配表達式exp
(?<!exp) :斷言自身出現的位置的前面不可以匹配表達式exp
常用正則表達式列表
- 匹配中文字符 [\u4e00-\u9fa5]
- 匹配空白行 \n\s*\r
- 匹配首尾空白字符 ^\s*|\s*$
- 匹配URL [a-zA-z]+://[ ^ \s]*
- 匹配QQ號 [1-9][0-9]{4,}
- 匹配中國郵政編碼 [1-9]\d{5}(?!\d)
- 匹配身份證 \d{15}|\d{18}
- 匹配ip地址 \d+.\d+.\d+.\d+
在java中使用正則表達式
基本用法:
//表達式對象
Pattern p=Pattern.compile("\\w+");
//創建matcher對象
Matcher m=p.matcher("asfadfa&&&sfal326v");
// boolean yesorno =m.matches();//嘗試將整個字符序列與該模式相匹配
// System.out.println(yesorno);
// boolean yesorno2=m.find();//該方法掃描輸入的數列,查找與該模式相匹配的下一個子序列
while(m.find())
{
System.out.println(m.group());//group(),group(0)匹配整個表達式的子字符串
System.out.println(m.group(0));
}
//表達式對象
Pattern p=Pattern.compile("([a-z]+)([0-9]+)");
//創建matcher對象
Matcher m=p.matcher("adfa465465**vak45464588**vakv464535");
while(m.find())
{
//System.out.println(m.group());//group(),group(0)匹配整個表達式的子字符串
System.out.println(m.group(0));
System.out.println(m.group(1));//匹配第一個括號
System.out.println(m.group(2));//匹配第二個括號
}
替換:
//表達式對象
Pattern p=Pattern.compile("[0-9]");
//創建matcher對象
Matcher m=p.matcher("adfa465465**vak45464588**vakv464535");
//替換
String newStr =m.replaceAll("#");
System.out.println(newStr);
網絡爬蟲(簡單操作)
package com.mhd.regexp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 網絡爬蟲(core)
* 獲得urlStr對應的網頁源碼內容
* @author CR553
*
*/
public class WebSpiderTest {
public static String getURLContent(String urlStr,String c)//獲得網址信息
{
StringBuilder sb=new StringBuilder();
try {
URL url=new URL(urlStr);
BufferedReader reader=new BufferedReader(new InputStreamReader(url.openStream(),Charset.forName(c)));
String temp="";
while((temp=reader.readLine())!=null)
{
sb.append(temp);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public static List<String> getMatherSubstrs(String destStr,String regexStr)//用正則表達式匹配並篩選自己需要的內容
{
// Pattern p=Pattern.compile("<a[\\s\\S]+?</a>");
Pattern p=Pattern.compile(regexStr);
Matcher m=p.matcher(destStr);
List<String> result=new ArrayList<String>();
while(m.find())
{
result.add(m.group());
}
return result;
}
public static void main(String[] args) {
String destStr= getURLContent("http://www.163.com","GBK");
List<String> result = getMatherSubstrs(destStr, "href=\"(.+?)\"");
for(String temp:result)
{
System.out.println(temp);
}
}
}