正则表达式

目录

一、正则表达式简介

二、匹配规则

2.1、匹配任意一个字符

2.2、匹配常用字符

2.3、匹配空格字符

2.4、匹配非数字

2.5、重复匹配

2.6、匹配开头和结尾

2.7、匹配指定范围

2.8、匹配分组

2.9、非贪婪匹配

2.10、分割字符串

2.11、搜索字符串

2.12、替换字符串


一、正则表达式简介

        正则表达式是用字符串描述的一个匹配规则,使用正则表达式可以快速判断给定的字符串是否符合匹配规则。Java 标准库 java.util.regex 内建了正则表达式引擎。

        常见问题:

        如何判断字符串是否有效电话号码 :例如  010-1234567  ,123ABC456,13537611000等。

        示例

        没有使用正则表达式粗略代码

	boolean isValidMobileNumber(String s) {
		// 是否是11位?
		if (s.length() != 11) {
			return false;
		}
		// 每一位都是0~9:
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c < '0' || c > '9') {
				return false;
			}
		}
		return true;
	}

         使用正则表达式

boolean isValidMobileNumber(String s) {
    return s.matches("\\d{11}");
}

        由此可见,使用正则表达式,不必编写复杂的代码来判断,只需要一个字符串表达式的正则规则即可。

二、匹配规则

字符说明
 \转义字符,正则表达式需要使用\\匹配
^匹配输入字符串开始位置
$匹配字符串结尾的位置
*零次或者多次匹配前面字符串或者子表达式
+一次或多次的字符串或子表达式
?

零次或一次匹配前面的字符或子表达式

{n}n是非负整数,正好匹配n次
{n,}n是非负整数,至少匹配n次
{n,m}n和m是非负整数,n<=m 。匹配至少n次,至多m次
.匹配单个字符,除“\r\n”
x|y匹配x或者y
[xyz]匹配包含xyz任何一个字符
[^xyz]匹配不包含xyz任何一个字符
[a-z]匹配a~z范围字符
\b匹配一个字边界
\B匹配非字边界
\d匹配数字。等效于[0-9]
\D匹配非数字。等效于[^0-9]
\f匹配换页符
\n匹配换行符
\r匹配回车键
\s匹配任何空白字符,包括空格、制表符、换页符。
\S匹配任何非空白字符
\t制表符匹配
\w匹配大小些字母、数字、下划线
\W非\w

        正则表达式规则是从左到右按规则匹配。对于正则表达式 “abc” 来说不能匹配“ab”,"Abc" ,“abcd”等其他字符串,只能匹配“abc”。

        正则表达式有特殊字符,那就需要用\转义。例如a\&,  其中\&就是匹配特殊字符&的。

        java中正则表达式是一个字符串。

        示例

public class Main {

	public static void main(String[] args) {
		abc();
		a();
		
		
	}

	private static void a() {
		String regex = "a\\&"; 对应的正则是a\&
		System.out.println("a&".matches(regex));// true
		System.out.println("a&&".matches(regex));//false
	}

	private static void abc() {
		String regex = "abc";
		System.out.println("abc".matches(regex));// true
		System.out.println("abcd".matches(regex));//false
		System.out.println("Abc".matches(regex));//false
	}

	

}

2.1、匹配任意一个字符

        正则表达式的 . 可以匹配一个任意字符。

        例如正则表达式  a.c可以匹配abc, a&c,acc 等。但是不能匹配ac,a&&c等,因为 . 匹配一个字符且限一个字符。

2.2、匹配常用字符

        用\w可以匹配一个字母、数字、下划线。

        例如 java\w 可以匹配 javac  、java_、java10。但是\w是不匹配#、空格。 

2.3、匹配空格字符

        用\s匹配一个空格字符。

        例如 \s 匹配 "a c"中的空格字符。

2.4、匹配非数字

        用\d可以匹配一个数字,而\D则匹配一个非数字。

        例如\D可以匹配A或者#非数字字符。

2.5、重复匹配

        可以使用 *,+,?,{n},  {n,},{n,m}等。

        *匹配任意个字符,包括0 个字符。

        例如A\d*可以匹配 A,A0,A3834

        +匹配至少一个字符。

        ?匹配0个或一个字符。

2.6、匹配开头和结尾

        用正则表达式进行多行匹配时,用^表示开头,$表示结尾。

        例如 ^A\d{2}$, 匹配 "A01"、"A58"

2.7、匹配指定范围

        可以使用 [...]指定范围。

        例如 [1-9]{6} 可以匹配  123456、654321。

2.8、匹配分组

        可以把一个子规则括起来实现分组。

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

public class Main {

	public static void main(String[] args) {
		String regex = "(\\d{3,4})\\-(\\d{6,8})";

		Pattern p = Pattern.compile(regex);

		String str = "010-12345678";

		Matcher m = p.matcher(str);

		if (m.matches()) {//判断是否匹配成功过
			String g = m.group();
			System.out.println(g);
			String g0 = m.group(0); // "010-12345678" ,0表示整个字符串
			String g1 = m.group(1);// "010" 1表示匹配第1个字符串
			String g2 = m.group(2);// "12345678" 2表示匹配第2个字符串
			System.out.println(g0);
			System.out.println(g1);
			System.out.println(g2);
		}

	}
}

        如果匹配成功过, m.group() 与g0 是一样的值,就是匹配的整个字符串。

2.9、非贪婪匹配

        先来看给示例,判断数字末尾0的个数。例如

        "123000" : 3个0

        "10100" : 2个0

        "1001" : 0个0

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

public class Main {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(\\d+)(0*)");
        Matcher matcher = pattern.matcher("1230000");
        if (matcher.matches()) {
            System.out.println("group1=" + matcher.group(1)); // "1230000"
            System.out.println("group2=" + matcher.group(2)); // ""
        }
    }
}
	

        打印第二子子串的是空字符串""。

        期望结果

input\d+0*
123000"123""000"
10100"101""00"
101"101"""

        但是实际结果

input\d+0*
123000"123"""
10100"101"""
101"101"""

        因为正则表达式默认使用贪婪匹配:任何一个规则,尽可能多地向后匹配,因此 \d+ 会把0包含进来。

        要让 \d+ 尽量少匹配,让0* 尽量多匹配,就必须让 \d+ 使用非贪婪匹配。在规则 \d+ 后面加个 ? 表示非贪婪匹配。

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

public class Main {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(\\d+?)(0*)");// 非贪婪
        Matcher matcher = pattern.matcher("1230000");
        if (matcher.matches()) {
            System.out.println("group1=" + matcher.group(1)); // "123"
            System.out.println("group2=" + matcher.group(2)); // "0000"
        }
    }
}
	

        示例

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

public class Main {
    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("(\\d??)(9*)");// 非贪婪
        Matcher matcher = pattern.matcher("9999");
        if (matcher.matches()) {
            System.out.println("group1=" + matcher.group(1)); // ""
            System.out.println("group2=" + matcher.group(2)); // "9999"
        }
    }
}
	

        (\\d??)(9*) 中 \d? 匹配0个或1个数字,后面第二 ?表示非贪婪匹配。因此 字符串 "9999",匹配到两个子串分别是 "" 和 "9999"。对于 \d? 来说可以匹配1个9, 也可以匹配0个9。但是因为后面?表示非贪婪匹配,它就会尽可能少匹配,结果是匹配了0个9。

2.10、分割字符串

        使用 string.split() 可以分割字符串。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
    	String strArr[] = "a b c".split("\\s");
    	System.out.println(Arrays.asList(strArr)); // [a, b, c]
    }
}
	

2.11、搜索字符串

        使用 Matcher 对象后,不需要调用 matches() 方法(因为匹配整个字符串肯定返回false),而是反复调用 find() 方法,在整个字符串中搜索能匹配上\\wo\\w规则的字串。并打印出来。

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

public class Main {
    public static void main(String[] args) {
    	String s = "the quick brown fox jumps over the lazy dog.";
    	Pattern p = Pattern.compile("\\wo\\w");
    	Matcher m = p.matcher(s);
    	while(m.find()) {
    		  String sub = s.substring(m.start(), m.end());
              System.out.println(sub);
    	}
    }
}
	

2.12、替换字符串

        可以使用字符串可以直接调用 string.replaceAll() , 第一个参数是正则表达式,第二个参数是待替换的字符串。

public class Main {
    public static void main(String[] args) {
        String s = "the quick brown fox jumps over the lazy dog.";
        String r = s.replaceAll("\\s([a-z]{4})\\s", " <b>$1</b> ");
        System.out.println(r);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2014Team

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值