1.8 正则表达式

它的作用是以简洁的形式描述一个字符串是否符合特定格式。一般大家讲到这块,就会列个表,然而一般列表的我都不怎么看(不知道为啥会失去兴趣),给几个常用的用法:

笔记 第1章 流与文件(13) 正则表达式_java

 自己匹配自己

Aa 和 Aa 是匹配的

笔记 第1章 流与文件(13) 正则表达式_正则_02

 方括号标识单个字符的范围

可以直接罗列 [abcde] 表示,一个字母,a/b/c/d/e 是匹配的其他不匹配

可以用横线描述范围[a-zA-Z]标识所有英文字母中的任意一个

笔记 第1章 流与文件(13) 正则表达式_正则表达式_03

 问号 ? 表示匹配 0 到 1 次,星号 * 表示匹配 1 到多次

[a-z]? 表示 1个或0个小写英文字母,匹配项: "a" ""

[a-z]+ 表示 1 次或多次匹配小写英文字母,匹配项:"a", "abcwfw"

笔记 第1章 流与文件(13) 正则表达式_p2p_04

 指定次数的大括号

{a,b} 表示前面的字符出现 a-b次

{a,} 表示前面字符出现 a 次以上

{,b}表示前面字母出现b次以下

{a} 表示前面字母刚好出现 a 次

笔记 第1章 流与文件(13) 正则表达式_p2p_05

 边界

^ 开头(也可表示非 [^0-9] 表示非数字)

$ 结尾

笔记 第1章 流与文件(13) 正则表达式_正则表达式_06

 字符

统一规则都是小写匹配大写不匹配

\d  意思是 digit 也就是匹配数字,和 [0-9] 一个意思

\D  意思是 非数字,和 [^0-9] 一样

\w 和 \W 一个是字符[a-zA-Z0-9_],一个非字符

\s 或 \S  space 也就是空格, \S 是非空格

示例:

11位手机号 ^[\d]{11}$

邮箱 ^([\w]+)[@]{1}([\w]+)\.com$

Java 正则写法:

Pattern pattern = Pattern.compile("正则串");

Matcher matcher = pattern.matcher("尝试匹配串");

if(matcher.matches()){}//配上了,处理

作者示例:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

import java.util.*;
import java.util.regex.*;

public class RegExTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter pattern: ");
String patternString = in.nextLine();
Pattern pattern = null;
try{
pattern = Pattern.compile(patternString);
}catch (PatternSyntaxException e){
System.out.println("Pattern syntax error");
System.exit(1);
e.printStackTrace();
}

while(true){
System.out.println("Enter string to match:");
String input = in.nextLine();
if(input == null || input.equals("")) return;

Matcher matcher = pattern.matcher(input);
if(matcher.matches()){
System.out.println("Match");
int g = matcher.groupCount();
if(g > 0){
for(int i = 0; i < input.length(); i++){
for(int j = 1; j <= g; j++){
if(i == matcher.start(j))
System.out.print('(');
}
System.out.print(input.charAt(i));
for(int j = 1; j <= g; j++){
if(i + 1 == matcher.end(j)){
System.out.print(')');
}
}
}
System.out.println();
}
}else{
System.out.println("No match");
}
}
}
}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

^[\d]{11}$

笔记 第1章 流与文件(13) 正则表达式_linq_07

^([\w]+)[@]{1}([\w]+)\.com$

笔记 第1章 流与文件(13) 正则表达式_linq_08

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

本人喜欢用正则的地方是空格处理:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

import java.util.*;

public class RegExTest {
public static void main(String[] args) {
String str = "I like write code.";

String rp = str.replaceAll("\\s+"," ");
System.out.println(rp);

String[] word = str.split("\\s+");
System.out.println(Arrays.toString(word));
}
}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

笔记 第1章 流与文件(13) 正则表达式_p2p_09

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

正则比较耗内存,对于复杂匹配,它的运行速度也有限,测试如下:

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class RegExTest {
public static void main(String[] args) {
String[] strs = new String[]{"a@1.com","bwwefwef!@","fwefw@sfwef@","hello@wefw.com","@fewgweg_t.com"};

long start = System.currentTimeMillis();
for(String str:strs){
System.out.println(match1(str));
}
long end = System.currentTimeMillis();
System.out.println(end-start);

start = System.currentTimeMillis();
for(String str:strs){
System.out.println(match2(str));
}
end = System.currentTimeMillis();
System.out.println(end-start);
}

private static boolean match1(String str){
if(str == null) return false;
Pattern pattern = null;
try{
pattern = Pattern.compile("^([\\w]+)[@]{1}([\\w]+)\\.com$");
}catch (PatternSyntaxException e){
System.out.println("Pattern syntax error");
System.exit(1);
e.printStackTrace();
}

Matcher matcher = pattern.matcher(str);
return matcher.matches();
}

private static boolean match2(String str){
if(str == null) return false;
int n =str.length();
//邮箱特点:以 .com 结尾
if(!str.endsWith(".com")) return false;
//邮箱特点: 有 @ 且只有1次,不在开头末尾(非.com末尾)
if(str.indexOf('@')==-1 || str.indexOf('@')==0 || str.indexOf('@')==n-5 || str.indexOf('@')!=str.lastIndexOf('@')) return false;


for(int i = 0; i < n-4; i++){
char c = str.charAt(i);
//其他必须是字母数字下划线
if(!Character.isDigit(c) && !Character.isLetter(c) && c != '_' && c != '@')
return false;
}
return true;
}
}

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

笔记 第1章 流与文件(13) 正则表达式_p2p_10

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

短短的几条数据,自己匹配和正则差距已经比较大,追求性能,或者一次需要做大量匹配串的情况,最好还是自己写。