1. 符号含义

1.1 字符表示

.  换行符之外的任何字符

\d [0,9]
\D 非数字
\s 空白符(空格 制表符 回车 换页 换行)
\S 非空白符
\w  英文字符+数字+下划线 [a-zA-Z0-9_]。 注意在py3中, 默认可匹配中文
\W 非英文字符[^\w]  
\b 单词边界(word boundary), 边界可以是 开头,结尾,[A-Za-z0-9_] 意外的如逗号等的字符. 

\  正则表达式中的转义。编程语言中\也表示转义,所以经常能看到\\连一块,不好看。

1.2 次数表示

* 出现次数>=0

? 出现0或1次

+ 出现次数 >0

{n} 表示出现刚好n次, 如 "\d{11}" 表示11位的手机号码. {n,} 表示出现n次及更多

1.3 位置表示

^ 一行的起始. 注意^符号在中括号外表示字符串的开头,中括号内表示取反。

$ 一行的结束

1.4 逻辑表示

 |  “或”的逻辑关系

^  "非"的逻辑关系, 需要用在中括号内。

1.5 括号

 ()  小括号, 同时有两种作用: 1)表示结合优先级; 2)子串提取. 那么问题来了,
        Q:我一个 pattern 中用到了两对小括号, 第一对仅表示结合优先级, 仅想提取第二对匹配的子串, 怎么办? 
        A: 都会得到匹配, 你只需拿 groups 中的第二个即可.

 [ ] 表示集合,包含其中的任意一个即可匹配, 如[\w,\.,_,-]表示英文字符, 小数点, 下划线 与 减号 中的任意一种都可以匹配.

2. 贪婪与非贪婪

贪婪:单个 pattern 下去匹配尽可能多的字符,也就是得到的匹配数最少。默认是贪婪的。非贪婪:在通配符后加`?`可以变为非贪婪. 

对于 text=abcdede

- `(\w+)de`
匹配到的是 `abcde`
- `(\w+?)de`
匹配到的是 `abc`

3. 例子

(-|\+)?\d+ , 可能以+号或-号开始,后面跟的有数字

\w+[\w,\.,_,-]*\w+@\w+[\w,\.,_,-]*\w+ ,邮箱规则

138\d{8}  ,138开头的中移动号码

Deep/(Deep_Network|Deep_Logits)/  , 描述 tensorflow 中 'Deep/Deep_Network' 及 'Deep/Deep_Logits' 两个 scope.

dense(_\d)*/lora_(A|B) , 描述 {dense/lora_A, dense_0/lora_B} 等字符串.

(.*OptimizeLoss(_\d)*)/(.*)/(part_\d+)  , 用来描述下面加黑部分的规律. 找到最后一个含 'Optimize'子 串的, 同时被斜杠围起来的地方, 此后是待提取内容. 内容后面还会有 part_数字的多余内容.

  1.  "Optimize/OptimizeLoss_1/Deep/Deep_Embeddings/u_province_emb_embedding/weights/part_2/AdagradDecay_1"
  2.  "Optimize/OptimizeLoss/Wide/Deep_Embeddings/u_gender_emb_embedding/weights/part_12/AdagradDecay"

有四组小括号, 会得到四个匹配. 因为有些小括号次数可以为0, 所以四个中的有些匹配可以为None.

4. java api

java.util.regex.Pattern
正则表达式编译后的表示、
Pattern java.util.regex.Pattern.compile(String regex)
将正则表达式编译成pattern。

java.util.regex.Matcher
代表字符串与正则表达式的匹配结果。
Matcher java.util.regex.Pattern.matcher(CharSequence input)
得到matcher。
boolean java.util.regex.Matcher.matches()
判断是否匹配.
String java.util.regex.Matcher.replaceAll(String replacement)
用replacement替代所有匹配。
boolean java.util.regex.Matcher.find()
将当前游标移动到下一个匹配,若后面没有了,返回false。
String java.util.regex.Matcher.group()
返回当前游标所指的匹配到的字符串。
int java.util.regex.Matcher.start()
返回当前匹配的下标。

4.1 代码示例

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.Test;

public class Example {
	@Test
	public void fun(){
		String a="http://a.com/12p/p123/12p23";
		Pattern pattern=Pattern.compile("\\d+");
		Matcher matcher=pattern.matcher(a);
		System.out.println(matcher.replaceAll("[digital]"));	
		 matcher=pattern.matcher(a);
		 while(matcher.find()){
			 System.out.println(matcher.group());
		 }
		
	}
}
/*http://a.com/[digital]p/p[digital]/[digital]p[digital]
12
123
12
23
*/

5.匹配子串抠取

有时我们不只是想知道是否匹配, 还想把部分匹配到的子串抠取出来.

要匹配并抠取的东西以小括号括起来,搭配 matcher.group(1) 使用。例子:

//从复杂的json中扣取清单id
public static Set<Long> getQdIds(String text){
	 Set<Long> set=new HashSet<>();
	 //  "qdId":"1000170000000050336"
	 // "qdId":"(\d{5,})"
	Pattern pattern=Pattern.compile("\"qdId\":\"(\\d{5,})\"");
	Matcher matcher=pattern.matcher(text);
	while(matcher.find())
		set.add(Long.valueOf(matcher.group(1)));
	return set;
}

更多推荐