JAVA正则表达式

内容主要来自菜鸟教程Java 正则表达式和《Java编程思想》

一、基本语法

在其他语言中,\\ 表示:我想要在正则表达式中插入一个普通的(字面上的)反斜杠,请不要给它任何特殊的意义。
在 Java 中,\\ 表示:我要插入一个正则表达式的反斜线,所以其后的字符具有特殊的意义。

插入一个普通的反斜杠,用\\\\
总之,就是把\\\用即可。

在此记录一些常见的字符简要说明,详细的字符说明可点此查看

1. 开始和结束

  • ^匹配输入字符串开始的位置
  • $匹配输入字符串结尾的位置

2. 次数

  • *零次或多次匹配前面的字符或子表达式(子表达式就是指用()括起来的pattern), 等效于 {0,}
  • +一次或多次匹配前面的字符或子表达式,等效于 {1,}
  • ?零次或一次匹配前面的字符或子表达式, 等效于 {0,1}
  • {n}正好匹配 n 次。
  • {n,}至少匹配 n 次。
  • {n,m}匹配至少 n 次,至多 m 次。注意逗号和数字之间不能有空格。

3. 非贪心模式匹配

  • ?当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?“只匹配单个"o”,而"o+“匹配所有"o”。

4. 关于pattern

  • (pattern)匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"\(“或者”\)"。
  • (?:pattern)匹配 pattern 但不捕获该匹配的子表达式
  • (?=pattern)执行正向预测先行搜索的子表达式
  • (?!pattern)执行反向预测先行搜索的子表达式

5. 点号(.)

  • .匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。

6. 或

  • x|y匹配 x 或 y

7. 字符集和字符范围

  • [xyz]字符集。匹配包含的任一字符。例如,"[abc]“匹配"plain"中的"a”。
  • [^xyz]反向字符集。匹配未包含的任何字符。例如,"[^abc]“匹配"plain"中"p”,“l”,“i”,“n”。
  • [a-z]字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。
  • [^a-z]反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。

8. 数字字符

  • \d数字字符匹配。等效于 [0-9]。
  • \D非数字字符匹配。等效于 [^0-9]。

9. 字母类字符

  • \w匹配任何单词字符,包括下划线。与"[A-Za-z0-9_]"等效。
  • \W与任何非单词字符匹配。与"[^A-Za-z0-9_]"等效。

10. 空白字符

  • \s匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。
  • \S匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。

11. 字边界

  • \b匹配一个字边界
  • \B非字边界匹配

小写字符表示“XXX匹配”,大写字母表示“非XXX匹配”。
数字、字母、空白字符、字边界依次是字母 d, w, s, b表示

12. 分别来说各个空白字符

  • \f换页符匹配。等效于 \x0c 和 \cL。
  • \n换行符匹配。等效于 \x0a 和 \cJ。
  • \r匹配一个回车符。等效于 \x0d 和 \cM。
  • \t制表符匹配。与 \x09 和 \cI 等效。
  • \v垂直制表符匹配。与 \x0b 和 \cK 等效。

13. 到捕获匹配的反向引用

  • \num匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。

14. 八进制转义码或反向引用、十六进制转义码等

  • \xn
  • \n
  • \nm
  • \nml
  • \un

二、Pattern & Matcher

1. 一般模式

Pattern pattern = Pattern.compile(REGEX);//获取Pattern对象
Matcher matcher = pattern.matcher(INPUT);//获取Matcher对象
		
matcher.XXXMethod();//开始使用Matcher对象的一堆方法
  • Pattern 类:
    pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。
  • Matcher 类:
    Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

2. Pattern对象的常用方法

除了上面提到的matcher(),还有:

  • public static boolean matches(String regex, CharSequence input)其实就是调用matcher的matches方法;一般就用String的matches了
  • public String[] split(CharSequence input)类似String的split;一般就用String的split了

3. Matcher对象的常用方法

(1)find / group

find()像迭代器一样,向前匹配符合条件的模式;group()输出当前匹配的模式。

Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher("Shit happens, deal with it!");
while (matcher.find()) {
	System.out.println("找到符合条件的字符串:" + matcher.group() + ",位置:" + matcher.start() + "-" + (matcher.end() - 1));
}
(2)按组匹配结果 group(i)

group()group(i)都要基于前一次匹配操作(如find())。

Pattern pattern = Pattern.compile("(\\S+)\\s+((\\S+)\\s+(\\S+))$");
Matcher matcher = pattern.matcher("Shit happens, deal with it!");
while (matcher.find()) {
	System.out.println(matcher.group());// group()其实就是group(0)
	for (int i = 0; i <= matcher.groupCount(); i++) {// groupCount()个数不包括group0
		System.out.println(i + ": " + matcher.group(i));
	}
}

输出:

deal with it!
0: deal with it!
1: deal
2: with it!
3: with
4: it!
(3)start / end

简单理解就是上次匹配的开始索引结束索引+1

(4)matches / lookingAt

matches方法要求整个序列匹配;lookingAt要求从第一个字符开始匹配,后面多出来没关系。

(5)replaceFirst / replaceAll

replaceFirst 替换首次匹配,replaceAll 替换所有匹配。

(6)appendReplacement / appendTail

appendReplacement: “渐进式”文本替换,可以在替换的过程中,变更replacement字符串;
appendTail:在执行一次或多次appendReplacement,将余下的字符串追加到sb。

This method reads characters from the input sequence, starting at the append position, and appends them to the given string buffer. It is intended to be invoked after one or more invocations of the appendReplacement method in order to copy the remainder of the input sequence.

private static String REGEX = "a*b";
private static String INPUT = "aabfooaabfooabfoobkkk";
private static String REPLACE = "-";
public static void main(String[] args) {
   Pattern p = Pattern.compile(REGEX);
   // 获取 matcher 对象
   Matcher m = p.matcher(INPUT);
   StringBuffer sb = new StringBuffer();
   while(m.find()){
      m.appendReplacement(sb,REPLACE);
   }
   m.appendTail(sb);
   System.out.println(sb.toString());
   // 结果:-foo-foo-foo-kkk
}
(7)reset

指定新的字符串;无参的reset指定到原字符串开头。

Pattern pattern = Pattern.compile("h\\w*");
Matcher matcher = pattern.matcher("Shit happens, deal with it!");
while (matcher.find()) {
	System.out.println(matcher.group());
}
matcher.reset("so what?!");
while (matcher.find()) {
	System.out.println(matcher.group());
}

4. 模式标记

可以通过标记指定匹配模式,如忽略大小写、忽略#之后的注释、多行模式、使用unicode编码等。
有两种指定方式:①在compile方法的第二个参数中指定;②直接在正则表达式中指定。
以下是忽略大小写的示例,其它的在需要时再查。

// 方式1
// Pattern pattern = Pattern.compile("Deal", Pattern.CASE_INSENSITIVE);
// 方式2
Pattern pattern = Pattern.compile("(?i)Deal");
Matcher matcher = pattern.matcher("Shit happens, deal with it!");
while (matcher.find()) {
	System.out.println(matcher.group());
}

三、String类中与正则表达式相关的方法

(1) matches

判断字符串是否符合正则表达式

System.out.println("-122".matches("(-|\\+)?\\d+"));

(2) split

从正则表达式匹配的地方分割开。与正则表达式匹配的部分在最终结果中都不会存在。

System.out.println(Arrays.toString("Shit happens, deal with it!".split(" ")));
// [Shit, happens,, deal, with, it!]
System.out.println(Arrays.toString("Shit happens, deal with it!".split("\\W+")));
// 从任何非字母的地方分割
// [Shit, happens, deal, with, it]

(3) replace / replaceFirst / replaceAll

System.out.println("Shit happens, deal with it!".replace(" ","-"));
// Shit-happens,-deal-with-it!
System.out.println("Shit happens, deal with it!".replaceFirst(" ","-"));
// Shit-happens, deal with it!
System.out.println("Shit happens, deal with it!".replaceAll("( h|d)\\w+"," XXX"));
// 替换h或d开头的任何单词
// Shit XXX,  XXX with it!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值