在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

Java与正则表达式

2017-2-7 13:41| 发布者: zhangjf| 查看: 455| 评论: 0

摘要: Java与正则表达式 标签: java基础 正则 正则语法 普通字符 字母, 数字, 汉字, 下划线, 以及没有特殊定义的标点符号都是普通字符. 表达式中的普通字符在匹配一个字符串时, 匹配与之相同的一个字符. 转义字符 ...
Java与正则表达式

标签: java基础


正则
正则语法 普通字符

字母, 数字, 汉字, 下划线, 以及没有特殊定义的标点符号都是普通字符. 表达式中的普通字符在匹配一个字符串时, 匹配与之相同的一个字符.


转义字符
字符 解释
n 换行符
t 制表符
^ $ ( ) { } ? + * | \ [ ] 匹配这些字符本身

标准字符集合
字符 匹配
d 任意一个数字
w 任意一个字母/数字/下划线
s 任意一个空格/制表符/换行符等空白字符
. 小数点在内的任意一个字符(除n外)
[sS] 匹配n在内的任意一个字符
注意大小写: 大写是取反
自定义字符集合

[] 方括号匹配方式, 能够匹配方括号中的任意一个字符.

表达式 解释
[ab5@v] 匹配a b 5 @ v中任意一个
[^ab5@v] 匹配a b 5 @ v之外任意一个
[f-k] 匹配f-k之间任意一个字母
[^f-k] 匹配f-k之外任意一个
[f-k0-3] 匹配f-k或0-3之间任意一个字母
[^f-k0-3] 不匹配f-k或0-3之间任意一个字母

注:

正则表达式中的特殊符号, 被包含到[]中, 则失去特殊意义, 除了- ^之外.
[]中的^表示取反的含义. []中的-表示范围的含义 标准字符集合(除小数点外),如果被包含于中括号中,则自定义集合将包含该集合.
如[d.-+]将匹配: 数字, 小数点, -, +
量词
量词 解释
{n} 表达式重复n次
{m,n} 表达式至少重复m次,最多重复n次
{m,} 表达式至少重复m次
? 匹配表达式0次或者1次
+ 表达式至少出现1次,相当于 {1,}
* 表达式不出现或出现任意次,相当于 {0,}

贪婪模式与非贪婪模式
贪婪模式: 匹配字符越多越好, 默认.
非贪婪模式: 匹配字符越少越好, 需要在量词后再加上一个?号.

示例

匹配手机号1[358]d{9} 匹配邮箱 ([w-.]+)@([0-9a-zA-Z-]+)(.[a-zA-Z]{2,4}){1,2}
字符边界

零宽匹配: 匹配的不是字符而是位置(符合某种条件的位置),不匹配任何字符.

字符 解释
^ 与字符串开始的地方匹配
$ 与字符串结束的地方匹配
b 匹配一个单词边界,也就是单词和空格之间的位置

注: b会匹配这样一个位置: 前面的字符与后面的字符不全是w


选择符与分组
表达式 解释
| 左右两边表达式之间 “或” 关系,匹配左边或右边
() 捕获组 被修饰时,()中的表达式可以作为整体被修饰; 取匹配结果时, ()中的表达式匹配到的内容可以被单独得到; 每一对括号会被分配一个编号(以(为准,从左到右: 从1开始)
(?:exp) 非捕获组 一些表达式中, 不得不使用(), 但又不需保存()中子表达式匹配的内容, 这时可以使用非捕获组来抵消()带来的副作用

注: 非捕获组可以用于当处理大量文本时用于优化内存分配.

反引用nnn
由上面可知, 捕获组默认被分配了编号, 通过反向引用, 可以对分组已捕获的字符串进行引用 示例
(w{2})1 匹配类似toto dodo gogo这样由一个单词复制而来得到的字符串
(img)w+1 匹配前后都是img的字符串
零宽断言(预搜索) 零宽度: 只进行子表达式的匹配, 匹配内容不计入最终的匹配结果. 位置匹配: 判断当前位置的前后字符是否符合指定的条件, 但不保留前后的字符.
表达式 解释
(?=exp) 断言自身出现的位置的后面能够匹配表达式exp
(?!exp) 断言自身出现的位置的后面不能匹配表达式exp
(?<=exp) 断言自身出现的位置的前面能够匹配表达式exp
(? 断言自身出现的位置的前面不能匹配表达式exp
示例
[a-z]+(?=ing) 匹配所有以ing结尾的单词, 但ing并不放入字符串
[a-z]+(?=d+) 匹配所有以数字结尾的单词
[a-z]+(?!d+) 匹配不以数字结尾的单词
(?<=(href=")) 匹配以href="开头的字符串
Java Pattern与Matcher java.util.regex包下提供的Pattern与Matcher两个类提供了在Java中的正则支持; Pattern对象是正则表达式编译后在内存中的表现形式, 因此, 正则表达式字符串必须先被编译为Pattern对象Pattern pattern = Pattern.compile("\w+");然后再利用该Pattern对象创建对象的Matcher对象Matcher matcher = pattern.matcher(input);. Matcher对象是一个对CharSequence执行匹配操作的正则引擎: 执行匹配所涉及的状态保留在Matcher对象中, 多个Matcher对象可共享同一个Pattern对象.
  1. /**
  2. * Created by jifang on 15/12/15.
  3. */
  4. public class LearnRegexp {
  5. @Test
  6. public void testSearch() {
  7. String input = "hello1997&&2000";
  8. // 将一个正则表达式编译成Pattern对象
  9. Pattern pattern = Pattern.compile("\w+");
  10. Matcher matcher = pattern.matcher(input);
  11. // matches尝试将整个字符序列与该模式匹配
  12. System.out.println(matcher.matches());
  13. // reset将matcher中的指针重新定位
  14. matcher.reset();
  15. // find 方法扫描整个字符串, 查找能否找到下一个符合该模式字符串
  16. while (matcher.find()) {
  17. String group = matcher.group();
  18. System.out.println(group);
  19. }
  20. }
  21. /**
  22. * 将所有的数字都替换成'#'
  23. */
  24. @Test
  25. public void testReplace() {
  26. String input = "1j2h3h4g5o";
  27. Matcher replace = Pattern.compile("[0-9]").matcher(input);
  28. input = replace.replaceAll("#");
  29. System.out.println(input);
  30. }
  31. /**
  32. * 将字符串按数字分割
  33. */
  34. @Test
  35. public void testSplit() {
  36. String input = "1j24h356h467g589o";
  37. String[] strings = input.split("\d+");
  38. for (String str : strings) {
  39. System.out.println(str);
  40. }
  41. }
  42. }
复制代码

由上例可以看到: 其实String中某些方法也支持正则表达式, 如split, replace等(Pattern,Matcher与String的其他用法请参考JDK文档).

小实验-抓取网页中所有的超链接
  1. /**
  2. * 模仿网络爬虫, 抓取网站html, 将里面所有的超链接都分析出来
  3. * Created by jifang on 15/12/15.
  4. */
  5. public class HtmlAnalyzer {
  6. private final String FILE_PATH = "/Users/jifang/save.txt";
  7. @Test
  8. public void client() throws IOException {
  9. String html = downloadHtml("http://www.163.com/", "gbk");
  10. // (?<=(href="))(?:[w./:?=&]+)(?=") 匹配url的正则
  11. Set<String> urlSet = analyzeHtml(html, "(?<=(href=\"))(?:[\w.\/\:\?\=\&]+)(?=\")");
  12. saveToFile(urlSet);
  13. System.out.println();
  14. }
  15. private String downloadHtml(String url, String charset) throws IOException {
  16. URL readUrl = new URL(url);
  17. BufferedReader reader = new BufferedReader(new InputStreamReader(readUrl.openStream(), charset));
  18. return CharStreams.toString(reader);
  19. }
  20. private Set<String> analyzeHtml(String html, String regex) {
  21. Set<String> urlSet = new HashSet<>();
  22. // 匹配url的正则表达式
  23. Matcher matcher = Pattern.compile(regex).matcher(html);
  24. while (matcher.find()) {
  25. String group = matcher.group();
  26. urlSet.add(group);
  27. }
  28. return urlSet;
  29. }
  30. private void saveToFile(Set<String> urlSet) throws IOException {
  31. PrintStream printer = new PrintStream(new FileOutputStream(FILE_PATH));
  32. for (String url : urlSet) {
  33. printer.println(url);
  34. }
  35. printer.flush();
  36. printer.close();
  37. }
  38. }
复制代码
附- 运行上程序需要在pom.xml中添加以下依赖
  1. <dependency>
  2. <groupId>com.google.guava</groupId>
  3. <artifactId>guava</artifactId>
  4. <version>18.0</version>
  5. </dependency>
复制代码

推荐几个正则验证工具:

Mac端: RegExRX Win端: RegexBuddy Web端: 在线正则表达式测试

参考

揭开正则表达式的神秘面纱 Java正则表达式教程

来自: http://blog.csdn.net/zjf280441589/article/details/50450169

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-7-9 09:56

Copyright 2015-2025 djqfx

返回顶部