正则
一、转义字符
- 反斜杠 \
- 点 .
- 星号 *
- 加号 +
- 问号 ?
- 左括号 { [ (
- 右括号 } ] )
- 竖线 |
- 脱字符 ^
- 美元符号 $
.*\\.csv // 匹配以.csv结尾的数据
需要在字符集中转义的字符(普通的元字符不需要在字符集中进行转义)
\ ] - ^
二、正则内容
2.1 特殊符号
一个指定范围内的任意符号:[0-9a-z] [aex] 表示匹配括号中字符集中的字符
一个指定范围外的任意符号:[\^0-9]
\d
:[0-9]
\D
:[\^0-9]
\w
:[0-9a-zA-Z_]
\W
:[\^0-9a-zA-Z_]
\s
:空白字符
\S
:非空白字符
2.2 通配符
?
{0,1}+
{1,}*
{0,}.*
尽可能多地匹配字符.*?
尽可能少地匹配字符
\\w+
和.*?
的异同:
同:都不能够匹配由空格分隔的连续多个单词
异:\\w+
匹配的字符只有字母、数字和下划线,而.*?
几乎匹配所有字符。
2.3 内容的重复
E{1,6}
:左侧的元素或者组合重复1-6次E{1,}
:左侧的元素至少重复1次E{,5}
:左侧的元素最多重复5次,可以没有E{5}
:左侧元素或者组合只能或者必须重复5次
2.4 边界
^
:首
$
:尾
\\b
:匹配单词边界
2.5 组合
【组合】
(...) 一个组合
((...)) 组合是可以嵌套的
(...(.1.)...(.2.)...(.3.))...(.4.)
0 -> (...(.1.)...(.2.)...(.3.))...(.4.) 完全整体
1 -> ...(.1.)...(.2.)...(.3.)
2 -> .1.
3 -> .2.
4 -> .3.
5 -> .4.
三、正则四大功能
3.1 格式匹配
// 判断字符串是否与正则表达式匹配的两个方法
public boolean matches(String regex)
Pattern.matches(String str,String regex)
常见的匹配案例
"123456@qq.com".matches("\\w+@[0-9a-z]{2,10}\\.(com|cn|org)$")
//邮箱 1223@ qq/136/hotmail . com
"^(https?|ftp|file):\\/\\/([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$"
//网址 http : // www . example.com
"^[\u4e00-\u9fa5]{2,}$"
//汉字 张三
"^[0-9]{1,}$"
//数值
"\d{4}-\d{2}-\d{2}"
//日期 2012-05-06
"\d{2}:\d{2}:\d{2}"
//时间 20:07:56
"1[3-9]\d{9}"
//电话
"\d{17}[0-9X]"
//身份证号
"<(S*?)[^>]>.?|<.*? />"
//html标记
"^[+-]?((\\d+(\\.)?)|(\\d*)\\.(\\d+))([eE][+-]?\\d+)?$"
//有效数字
3.2 拆分(正难则反)
"123.456#789?abc,def".split("[^0-9a-zA-Z]+")//注意 反向匹配一般要带+号
"123.456#789?abc,def".split("\\.|#|\\?|,")
3.3 替换
"123.456#789?abc,def".replaceAll("[^0-9a-zA-Z]+", " ");
3.4 分组提取
0
表示整个字符串只有用小括号括起来的才能被保留
首尾不存在
^$
说明不要求匹配整个字符串
// 进行分组提取的两个核心方法:
Pattern pat = Pattern.compile("");// 括号内写分组匹配的正则表达式
Matcher mat = pat.matcher(line);// 返回一个模式匹配器
String line = "98662432,320593836,1,96nn52n,6562,2014-12-06 10";
Pattern pat = Pattern.compile("^(\\d+),.*?,([1-4]),.*?,(\\d+),(\\d{4}-\\d{2}-\\d{2}) \\d{2}$");
final Matcher mat = pat.matcher(line);
if(mat.matches()){
System.out.println(mat.group(1));
System.out.println(mat.group(2));
System.out.println(mat.group(3));
System.out.println(mat.group(4));
}else{
System.out.println("匹配不上");
}
分组提取中正则表达式常见写法:
"(\\\d+\\\.?\\\d+?)"
//整数或小数
"(.*?)"
//字符串
"(true|false)"
// 布尔值
3.5 提取符合条件的部分字符串
public static void main(String[] args) {
String str = "<img src=``test.jpg` width=`60px` height=`80px`/>";
final Pattern p1 = Pattern.compile("src=`.*`");// 此处不能加^ $来表示字符串的边界
final Pattern p2 = Pattern.compile("src=`.*?`");
final Matcher m1 = p1.matcher(str);
final Matcher m2 = p2.matcher(str);
if(m1.find()){
// matcher()全部匹配,find()部分匹配
System.out.println("根据p1切分的结果:");
System.out.println("匹配数量:"+m1.groupCount());
for (int i = 0; i <= m1.groupCount(); i++) {
System.out.println(m1.group(i));
}
}
if(m2.find()){
System.out.println("根据p2切分的结果:");
System.out.println("匹配数量:"+m2.groupCount());
for (int i = 0; i <= m2.groupCount(); i++) {
System.out.println(m2.group(i));
}
}
}
四、注意
- 当分隔符位于字符串的前面或者后面的时候,会产生一个空字符串,如果分隔符为空格,此时可以先用trim()去掉首尾的空格,再进行split()
- 如果字符串中只包含分隔符的话,即使提前trim()过了还是会留有一个空字符串。
- 在对文本文件中的每一行进行数据处理的时候,应该先进行trim(),是因为文本文件的行两端极易出现空格。
- 对于replaceAll(line,'[\^A-Za-z ]+',' ');在替换时选择
+
的原因是进行批量替换效率更高。