介紹
正則表達(dá)式犹芹,又稱(chēng)正規(guī)表示法、常規(guī)表示法(英語(yǔ):Regular Expression阁苞,在代碼中常簡(jiǎn)寫(xiě)為regex困檩、regexp或RE),計(jì)算機(jī)科學(xué)的一個(gè)概念那槽。正則表達(dá)式使用單個(gè)字符串來(lái)描述悼沿、匹配一系列符合某個(gè)句法規(guī)則的字符串。在很多文本編輯器里骚灸,正則表達(dá)式通常被用來(lái)檢索糟趾、替換那些符合某個(gè)模式的文本。
幾個(gè)重要的正則表達(dá)式:
- 用戶(hù)名(6-15位字母和數(shù)字的組合): /^(?=.[A-Za-z])(?=.\d)[A-Za-z\d]{6,15}$/;
- 電話(huà) :/^1[34578]\d{9}$/
- 兩位小數(shù): /^[0-9]+.?[0-9]{0,2}$/
- 郵箱: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/
- url:/^[a-zA-z]+://(\w+(-\w+))(\.(\w+(-\w+)))(\?\S)?$/
更多數(shù)字的正則
常用應(yīng)用
主要是分三種應(yīng)用
- 文本替換 例如 ide
- 輸入驗(yàn)證 例如 登錄驗(yàn)證
- 文本摘取 例如爬蟲(chóng)
案例
/**
* 字符串規(guī)則驗(yàn)證
* @param regexp 正則表達(dá)式
* @param str 待驗(yàn)證字符串
* @return 字符串是否符合正則表達(dá)式規(guī)則
*/
public static boolean test(String regexp,String str){
//編譯正則表達(dá)式 返回Pattern對(duì)象
Pattern pattern=Pattern.compile(regexp);
//驗(yàn)證字符串返回Matcher對(duì)象
Matcher match = pattern.matcher(str);
//返回是否在字符串中找到匹配的子字符串
return match.find();
}
正則表達(dá)式規(guī)則
- {} 表示個(gè)數(shù)
- [] 表示字符集合
- () 表示組
- \ 轉(zhuǎn)譯
1.{} 表示個(gè)數(shù)
正則表達(dá)式 實(shí)際上就是通過(guò)一個(gè)簡(jiǎn)化的規(guī)則去描述字符串
比如 "aaaa..." 有25個(gè)a
正則表達(dá)式的描述就是 a{25}
"aaa....bbb...."25個(gè)a 和26個(gè)b
正則表達(dá)式的描述就是 a{25}b{26}
這是精確匹配
假設(shè) 有一堆字符串 "a..."25個(gè)a "a..."10個(gè)a "a..."6個(gè)a
a{6,25} 表示 a個(gè)數(shù)可以是6個(gè) 7個(gè)甚牲,8個(gè) 义郑。。鳖藕。25個(gè)
這種是模糊匹配
假設(shè) 有一堆字符串 "a..."25個(gè)a "a..."10個(gè)a "a..."6個(gè)a
a{6,25} 表示 a個(gè)數(shù)可以是6個(gè) 7個(gè)魔慷,8個(gè) 只锭。著恩。。25個(gè)
這種是模糊匹配
那么有兩個(gè)特殊的字符 來(lái)表示
a{1,} === a+ +表示1到多個(gè)
a{0,} === a* *表示0到多個(gè)
2.[] 集合
"a..b..aabbababab.."26個(gè)字符
假設(shè)有這個(gè)字符串
ab交替混合 不規(guī)則出現(xiàn)
正則表達(dá)式的描述就是 [ab]{26}
[1-5]{26}===[12345]{26}
[a-e]===[abcde]
[0-9]====\d 表示0-9
[A-Za-z0-9_]===\w 表示所有字符
[^0-3]表示不出現(xiàn)0123
3.\ 轉(zhuǎn)義符
\n 換行符 \t tab符 \r 回車(chē)符 \f 換頁(yè)符 \v 垂直tab
\d 數(shù)字 \w 字符和數(shù)字加下劃線(xiàn) \s [ \n\t\r\f\v]
\W [^\w] \D [^\d] \S [^\s]
\b 單詞邊界 \B [^\b]
4.() 組
()括起來(lái)的正則表達(dá)式 表示一個(gè)組
被括起來(lái)的正則表達(dá)式匹配的字符 可以用$1表示
假設(shè)有2個(gè)()
那么第一個(gè)就是$1 第二個(gè)就是$2
eg1:
System.out.println("123---123-----123".replaceAll("(1)2(3)","$1a$2b"));
//輸出
//1a3b---1a3b-----1a3b
eg2:
abc
bcd
ece
對(duì)文件每行的頭尾加上單引號(hào)
System.out.println("abc\nbcd\ncdc\n".replaceAll("(\\w+)\\n","'$1'\n"));
完成一個(gè)Regexp的工具類(lèi)(成果)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by ASUS on 2017/9/11.
*/
public class RegExp { /**
* 字符串規(guī)則驗(yàn)證
* @param regexp 正則表達(dá)式
* @param str 待驗(yàn)證字符串
* @return 字符串是否符合正則表達(dá)式規(guī)則
*/
public static boolean test(String regexp,String str){
//編譯正則表達(dá)式 返回Pattern對(duì)象
Pattern pattern= Pattern.compile(regexp);
//驗(yàn)證字符串返回Matcher對(duì)象
Matcher match = pattern.matcher(str);
//返回是否在字符串中找到匹配的子字符串
return match.find();
}
/**
* 替換字符串
* @param source
* @param regexp
* @param str
* @return
*/
public static String replace(String source,String regexp,String str){
return source.replaceAll(regexp,str);
}
/**
* 正則表達(dá)式替換方程
*/
public interface ReplaceFunc{
/**
* 根據(jù)輸入的匹配項(xiàng)返回替換的對(duì)象
* @param args args[0]=matcher args[1]=$1,args[2]=$2 ......
* @return 替換字符串
*/
String func(String... parms);
}
/**
* 可控的替換過(guò)程
* @param source 源字符串
* @param regexp 正則表達(dá)式
* @param func 替換方法
* @return
*/
public static String replace(String source,String regexp,ReplaceFunc func){
Pattern pattern=Pattern.compile(regexp);
Matcher matcher = pattern.matcher(source);
StringBuffer sb = new StringBuffer();
while(matcher.find()){
String parms[]=new String[matcher.groupCount()+1];
for (int i = 0; i <parms.length; i++) {
parms[i]=matcher.group(i);
}
if(parms.length!=0){
matcher.appendReplacement(sb, func.func(parms));
}
}
matcher.appendTail(sb);
return sb.toString();
}
}
例子
這樣我可以控制正則匹配的每一步 并作出對(duì)應(yīng)的操作來(lái)修改返回字符串
eg1:
String result = RegExp.replace("abc\nbcd\ncdc\n", "(\\w+)\\n", new RegExp.ReplaceFunc() {
@Override
public String func(String... parms) {
String $1 = parms[1];
if("abc".equals($1)){
return "'ABC'\n";
}else if("bcd".equals($1)){
return "'BcD'\n";
}
return "'" + $1 + "'\n";
}
});
System.out.println(result);
eg2:
String abc= RegExp.replace("123\n--123\n--123\n", "(1+)2(3)", new RegExp.ReplaceFunc() {
@Override
public String func(String ...parms) {
String $1=parms[1];
String $2=parms[2];
return $1+"a"+$2;
}
});
System.out.println(abc);