文本匹配
正则表达式,又称正规表示法、常规表示法(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。
常用应用
主要是分两种应用
- 文本替换 例如 ide
- 输入验证 例如 登录验证
- 文本摘取 例如爬虫
案例
java中的正则表达式是通过Pattern实现的
/**
* 字符串规则验证
* @param regexp 正则表达式
* @param str 待验证字符串
* @return 字符串是否符合正则表达式规则
*/
public static boolean test(String regexp,String str){
//编译正则表达式 返回Pattern对象
Pattern pattern=Pattern.compile(regexp);
//验证字符串返回Matcher对象
Matcher match = pattern.matcher(str);
//返回是否在字符串中找到匹配的子字符串
return match.find();
}
正则表达式规则
[] 表示字符集合
() 表示组
\ 转译
{} 表示个数
正则表达式 实际上就是通过一个简化的规则去描述字符串
比如 "aaaa..." 有25个a
正则表达式的描述就是 a{25}
"aaa....bbb...."25个a 和26个b
正则表达式的描述就是 a{25}b{26}
这是精确匹配
假设 有一堆字符串 "a..."25个a "a..."10个a "a..."6个a
a{6,25} 表示 a个数可以是6个 7个,8个 。。。25个
这种是模糊匹配
假设 有一堆字符串 "a..."25个a "a..."10个a "a..."6个a
a{6,25} 表示 a个数可以是6个 7个,8个 。。。25个
这种是模糊匹配
那么有两个特殊的字符 来表示
a{1,} === a+ +表示1到多个
a{0,} === a* *表示0到多个
[] 集合
"a..b..aabbababab.."26个字符
假设有这个字符串
ab交替混合 不规则出现
正则表达式的描述就是 [ab]{26}
[1-5]{26}===[12345]{26}
[a-e]===[abcde]
[0-9]====\d 表示0-9
[A-Za-z0-9_]===\w 表示所有字符
[^0-3]表示不出现0123
\ 转义符
\n 换行符 \t tab符 \r 回车符 \f 换页符 \v 垂直tab
\d 数字 \w 字符和数字加下划线 \s [ \n\t\r\f\v]
\W [^\w] \D [^\d] \S [^\s]
\b 单词边界 \B [^\b]
() 组
()括起来的正则表达式 表示一个组
被括起来的正则表达式匹配的字符 可以用$1表示
假设有2个()
那么第一个就是$1 第二个就是$2
System.out.println("123---123-----123".replaceAll("(1)2(3)","$1a$2b"));
//输出
//1a3b---1a3b-----1a3b
假设文件a
abc
bcd
ece
对文件每行的头尾加上单引号
String s=readFile();
writeFile(s.replaceAll("(\\w+)\\n","'$1'\n"))
完成一个Regexp的工具类
test方法
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegExp {
/**
* 字符串规则验证
* @param regexp 正则表达式
* @param str 待验证字符串
* @return 字符串是否符合正则表达式规则
*/
public static boolean test(String regexp,String str){
//编译正则表达式 返回Pattern对象
Pattern pattern= Pattern.compile(regexp);
//验证字符串返回Matcher对象
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);
}
/**
* 正则表达式替换方程
*/
public interface ReplaceFunc{
/**
* 根据输入的匹配项返回替换的对象
* @param args args[0]=matcher args[1]=$1,args[2]=$2 ......
* @return 替换字符串
*/
String func(String... args);
}
/**
* 可控的替换过程
* @param source 源字符串
* @param regexp 正则表达式
* @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();
}
}
例子
这样我可以控制正则匹配的每一步 并作出对应的操作来修改返回字符串
String result = RegExp.replace("abc\nbcd\ncdc\n", "(\\w+)\\n", new RegExp.ReplaceFunc() {
@Override
public String func(String... args) {
String $1 = args[1];
if("abc".equals($1)){
return "'ABC'\n";
}else if("bcd".equals($1)){
return "'BcD'\n";
}
return "'" + $1 + "'\n";
}
});
System.out.println(result);