在一个许多文字的文本中查找你所需要的文字并不简单,但是正则表达式让查找字符变得非常优雅。
今天我们就来学一学Java的正则表达式。
第一步,介绍Java中如何利用上面的正则语法来构造正则表达式呢
看下面的例子
public static void main(String[] args) {
// 正则表达式
String regex = "";
// 编译正则表达式
Pattern pattern = Pattern.compile(regex);
// 被匹配的字符串
String str = "b";
// 设置被匹配的字符串
Matcher matcher = pattern.matcher(str);
// 匹配方式
// 全部匹配
if (matcher.matches()) {
// 如果匹配成功
System.out.println(str);
}
}
上面例子就是Java简单的使用正则表达式的过程。首先我们主要学习正则表达式的用法
第二步 学习正则表达式
常用的正则字符
字符 匹配
x 字符 x
\\ 反斜线字符
\0n 带有八进制值 0 的字符 n (0 <= n <= 7)
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7)
\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 带有十六进制值 0x 的字符 hh
\uhhhh 带有十六进制值 0x 的字符 hhhh
\t 制表符 ('\u0009')
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
\f 换页符 ('\u000C')
\a 报警 (bell) 符 ('\u0007')
\e 转义符 ('\u001B')
\cx 对应于 x 的控制符
字符 匹配
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
[ ] 代表逻辑框 默认为或
字符 匹配
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超过 m 次
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超过 m 次
做个小程序来说明使用正则表达式的步骤
目的从一个网页代码的文本文件中提取出链接出来
<td>172</td><td>0</td><td><a href='?t=lock&id=69260885' class='lock'>禁止评论</a></td><td><a href='/postedit/69260885'>编辑</a> | <a href='?t=top&id=69260885'>置顶</a> | <a href='?t=del&id=69260885' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69260885);' class='cat'>分类</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69259533' target=_blank>如何使用FastDFS上传图片</a><span class='gray'>(2017-04-13 22:34)</span></td><td> </td><td>170</td><td>0</td><td><a href='?t=lock&id=69259533' class='lock'>禁止评论</a></td><td><a href='/postedit/69259533'>编辑</a> | <a href='?t=top&id=69259533'>置顶</a> | <a href='?t=del&id=69259533' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69259533);' class='cat'>分类</a></td></tr><tr><td class='tdleft'>
<a href='http://blog.csdn.net/a609733301/article/details/69258951' target=_blank>数据结构与算法之高级排序(希尔/堆)<十一></a><span class='gray'>(2017-04-09 15:53)</span></td><td> </td><td>98</td><td>0</td><td><a href='?t=lock&id=69258951' class='lock'>禁止评论</a></td><td><a href='/postedit/69258951'>编辑</a> | <a href='?t=top&id=69258951'>置顶</a> | <a href='?t=del&id=69258951' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258951);' class='cat'>分类</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258965' target=_blank>数据结构与算法之基础排序(冒泡/插入/选择)<十></a><span class='gray'>(2017-04-09 15:51)</span></td><td> </td><td>99</td><td>0</td><td><a href='?t=lock&id=69258965' class='lock'>禁止评论</a></td>
<td><a href='/postedit/69258965'>编辑</a> | <a href='?t=top&id=69258965'>置顶</a> | <a href='?t=del&id=69258965' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258965);' class='cat'>分类</a></td></tr><tr><td class='tdleft'>
<a href='http://blog.csdn.net/a609733301/article/details/69258958' target=_blank>数据结构与算法之高级排序(快速/归并)<十二></a><span class='gray'>(2017-04-09 15:50)</span></td>
<td> </td><td>106</td><td>0</td><td><a href='?t=lock&id=69258958' class='lock'>禁止评论</a></td><td><a href='/postedit/69258958'>编辑</a> | <a href='?t=top&id=69258958'>置顶</a> | <a href='?t=del&id=69258958' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258958);' class='cat'>分类</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258919' target=_blank>数据结构与算法之优先队列<九></a><span class='gray'>(2017-04-07 17:55)</span></td><td> </td><td>110</td><td>0</td><td><a href='?t=lock&id=69258919' class='lock'>禁止评论</a></td><td><a href='/postedit/69258919'>编辑</a> | <a href='?t=top&id=69258919'>置顶</a> | <a href='?t=del&id=69258919' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258919);' class='cat'>分类</a>
</td></tr><tr><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258858' target=_blank>数据结构与算法之散列(分离链接法)<七></a><span class='gray'>(2017-04-07 17:39)</span></td><td> </td>
<td>131</td><td>0</td><td><a href='?t=lock&id=69258858' class='lock'>禁止评论</a></td><td><a href='/postedit/69258858'>编辑</a> | <a href='?t=top&id=69258858'>置顶</a> | <a href='?t=del&id=69258858' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258858);' class='cat'>分类</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258910' target=_blank>数据结构与算法之散列(线性/平方/双平方探测法)<八></a><span class='gray'>(2017-04-07 17:37)</span></td><td> </td><td>116</td><td>0</td><td><a href='?t=lock&id=69258910' class='lock'>禁止评论</a></td><td><a href='/postedit/69258910'>编辑</a> | <a href='?t=top&id=69258910'>置顶</a> | <a href='?t=del&id=69258910' name=del>删除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258910);' class='cat'>分类</a></td></tr>
第一步确定正则表达式
分析过程
首先观察链接的格式
http://blog.csdn.net/a609733301/article/details/69258919
根据需求找出不变的部分
这里为了使匹配稍微复杂点不设置不变得部分
因此可以初步确定格式
**://***.****.***/***/***/***/***
这样的格式
将变化的部分装化成正则表达式
一步一步来
首先根据需求来确定对各个变化部分是否有约束
为了复杂我尽量加点约束
我想匹配http或者https以及ftp这几种特定的首部
[(http)(https)(ftp)]
为了方便直接可以
\\w{3,5}+ 至少三个不超过5个的字符 代表***
\\w{3,5}+:// 代表**://
接下来对于网址
直接可以
(\\w+\\.)+ 几个字符加上一个.的形式出现多次 代表***.****.
(\\w+/)+ 几个字符加上一个/的形式出现多次 代表 ***/***/
\\w+ 代表最后的几个字符 ***
最终正则表达式是
\\w{3,5}+://(\\w+\\.)+(\\w+/)+\\w+
对正则表达式进行优化(会使其更难与阅读)
\\w{3,5}+://(\\w+[\\./])+\\w+
确定好正则表达式后开始匹配
public static void main(String[] args) {
//获取指定匹配文件
File file = new File("F:/JavaCode/JavaResource/JavaSourceCode/src/test/text.txt");
//创建存储文件
File file1 = new File("F:/JavaCode/JavaResource/JavaSourceCode/src/test/text1.txt");
//创建存储字符串
StringBuffer stringBuffer = new StringBuffer();
//编译正则表达式
Pattern pattern = Pattern.compile("\\w{3,5}+://(\\w+[\\./])+\\w+");
try {
//文件读取对象
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//文件写入对象
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file1));
//读取文件直到末尾
while (bufferedReader.ready()) {
//一行一行的读
String readLine = bufferedReader.readLine();
//匹配这一行
Matcher matcher = pattern.matcher(readLine);
//匹配到结果
while (matcher.find()) {
//将匹配的结果存入字符串中
stringBuffer.append(matcher.group());
stringBuffer.append('\n');
}
}
//将匹配字符存入文件
bufferedWriter.write(new String(stringBuffer));
bufferedReader.close();
bufferedWriter.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
结果
http://blog.csdn.net/a609733301/article/details/69259533
http://blog.csdn.net/a609733301/article/details/69258951
http://blog.csdn.net/a609733301/article/details/69258965
http://blog.csdn.net/a609733301/article/details/69258958
http://blog.csdn.net/a609733301/article/details/69258919
http://blog.csdn.net/a609733301/article/details/69258858
http://blog.csdn.net/a609733301/article/details/69258910
总结
正则表达式的使用
1.首先是根据需求来确定匹配字符的不变与变化部分
2.将变化部分根据约束一步一步替换成正则表达式。
3.总表达式可以根据情况进行优化
提示
不可能一次就完美匹配到结果,较好的方法是先粗糙匹配,再逐渐细腻化。