Java中正则表达式处理

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

1、所有的正则表达式都是以^ 开头, 以$结尾。 2、反斜线\在Java中使用特殊用途的,所以。不要直接使用\反斜线。如果想使用反斜线请使用\\ 因为有些字符是需要表达特别含义的,所以Java用\ 作为转义字符,比如\n,在Java中表示换行。所以使用反斜线则需要转义故而形式为\\ 3、? 代表匹配某个模式的0个字符或者1个字符 比如,我想匹配的data后面的字符是一个数字,这个数字可以不出现,但是只能出现1次。 public class RegularTest {

@Test

public void testRegex(){

String regex = "^data\\d?$";

String value1 = "data";

String value2 = "data1";

String value3 = "data2";

String value4 = "data3";

String value5 = "data33";

System.out.println(Pattern.matches(regex, value1));

System.out.println(Pattern.matches(regex, value2));

System.out.println(Pattern.matches(regex, value3));

System.out.println(Pattern.matches(regex, value4));

System.out.println(Pattern.matches(regex, value5));

//true

//true

//true

//true

//false

}

}

4、* 代表匹配某个模式0个或者多个字符。他在? 基础上,增强了。 比如我想能匹配多个数字字符。 public class RegularTest {

@Test

public void testRegex(){

String regex = "^data\\d*$";

String value1 = "data";

String value2 = "data1";

String value3 = "data2";

String value4 = "data3";

String value5 = "data33";

String value6 = "data334";

String value7 = "datab";

System.out.println(Pattern.matches(regex, value1));

System.out.println(Pattern.matches(regex, value2));

System.out.println(Pattern.matches(regex, value3));

System.out.println(Pattern.matches(regex, value4));

System.out.println(Pattern.matches(regex, value5));

System.out.println(Pattern.matches(regex, value6));

System.out.println(Pattern.matches(regex, value7));

//true

//true

//true

//true

//true

//true

//false

}

}

5、+ 代表此模式,必须出现一次。

​ 比如* 比较,这个模式不出现则为false.

public class RegularTest {

@Test

public void testRegex(){

String regex = "^data\\d+$";

String value1 = "data";

String value2 = "data1";

String value3 = "data2";

String value4 = "data3";

String value5 = "data33";

String value6 = "data334";

String value7 = "datab";

System.out.println(Pattern.matches(regex, value1));

System.out.println(Pattern.matches(regex, value2));

System.out.println(Pattern.matches(regex, value3));

System.out.println(Pattern.matches(regex, value4));

System.out.println(Pattern.matches(regex, value5));

System.out.println(Pattern.matches(regex, value6));

System.out.println(Pattern.matches(regex, value7));

//false

//true

//true

//true

//true

//true

//false

}

}

这种我们称为限定符,用于规定给定组件必须要出现多少次才能满足匹配的。限定表总结如下:

字符描述*匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”*。** 等价于 {0,}。+匹配前面的子表达式一次或多次。例如,zo+ 能匹配 “zo” 以及 "zoo",但不能匹配 “z”*。*+ 等价于 {1,}。?匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 “do” 、 “does”*、 **“doxy”** 中的 **“do”** 。*? 等价于 {0,1}。{n}n 是一个非负整数。匹配确定的 n 次。例如,o{2} 不能匹配 “Bob” 中的 o,但是能匹配 “food” 中的两个 o。{n,}n 是一个非负整数。至少匹配n 次。例如,o{2,} 不能匹配 “Bob” 中的 o,但能匹配 “foooood” 中的所有 o。o{1,} 等价于 o+**。*o{0,} 则等价于 o。{n,m}m 和 n 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如,o{1,3} 将匹配 “fooooood” 中的前三个 o。o{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。

如果我们想要表示一个范围内的字符,可以使用方括号:

public static void main(String[] args) {

String str = "abcabccaa";

System.out.println(str.matches("[abc]*")); //表示abc这几个字符可以出现 0 - N 次

}

对于普通字符来说,我们可以下面的方式实现多种字符匹配:

字符描述[ABC]匹配 […] 中的所有字符,例如 [aeiou] 匹配字符串 “google runoob taobao” 中所有的 e o u a 字母。[^ABC]匹配除了 […] 中字符的所有字符,例如 [^aeiou] 匹配字符串 “google runoob taobao” 中除了 e o u a 字母的所有字母。[A-Z][A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。.匹配除换行符(\n、\r)之外的任何单个字符,相等于 [^\n\r][\s\S]匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]

当然,这里仅仅是对正则表达式的简单使用,实际上正则表达式内容非常多,如果需要完整学习正则表达式,可以到:https://www.runoob.com/regexp/regexp-syntax.html

正则表达式并不是只有Java才支持,其他很多语言比如JavaScript、Python等等都是支持正则表达式的。

Parttern

Java提供了Parttern 对我们输入的正则表达式进行一个封装处理,调用compile()编译方法就可以完成对正则的封装。

compile

public class PatternTest {

@Test

public void compile(){

Pattern pattern1 = Pattern.compile("[a-z]");

Pattern pattern2 = Pattern.compile("[A-Z]");

Pattern pattern3 = Pattern.compile("\\d");

}

}

matcher

定义好正则匹配对象后,调用matcher() 将需要校验字符串注入,返回一个校验结果的Matcher 对象。

public class PatternTest {

@Test

public void matcher() {

Pattern pattern1 = Pattern.compile("[a-z]");

String newcheckStr = "1111";

//执行匹配,结果封装到Matcher对象中

Matcher matcher = pattern1.matcher(newcheckStr);

}

}

Matcher

find

校验结果对象Matcher的find()方法可以获取到本次校验结果,校验通过返回true 校验不通过返回false

public class MatchResultTest {

@Test

public void find() {

//校验

Pattern pattern1 = Pattern.compile("[a-z]");

String newCheckStr = "1111";

Matcher matcher = pattern1.matcher(newCheckStr);

//获取本此校验结果

boolean validResult = matcher.find();

System.out.println(validResult);

}

}

toMatchResult

通过Pattern,对输入的字符串进行匹配,得到匹配器实例Matcher,可以通过find()方法判断是否匹配上。如果匹配上,可以通过toMatchResult得到匹配结果值。

package com.wnx.naizi;

import org.junit.jupiter.api.Test;

import java.util.regex.MatchResult;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class MatchResultTest {

@Test

public void toMatchResult() {

//匹配${}的正则

Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");

String input = "我的名字是${name},手机号${phone},地址${address}";

Matcher matcher = pattern.matcher(input);

//获取匹配结果值

while (matcher.find()){

MatchResult matchResult = matcher.toMatchResult();

System.out.println(matchResult.group());

}

//${name}

//${phone}

//${address}

}

}

start&end

获取匹配到的子串在input的开始下标的终止下标。

public class MatchResultTest {

@Test

public void toMatchResult() {

//匹配${}的正则

Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");

String input = "我的名字是${name},手机号${phone},地址${address}";

Matcher matcher = pattern.matcher(input);

//获取匹配结果值

while (matcher.find()){

MatchResult matchResult = matcher.toMatchResult();

System.out.println(matchResult.group());

System.out.println(matchResult.start());

System.out.println(matchResult.end());

}

}

}

group

简介 最近在做一个项目,需要使用matcher.group()方法匹配出需要的内容

java.time.MatchResult.group()方法返回与上一个匹配项匹配的输入子序列。

正则表达式分组 是从左至右计算其左括号有几个就可以分为几组。编号从1开始

第一组 ((A)(B(C)))

第二组 (A)

第三组 (B(C))

第四组 (C)

编号从1 开始 所以 x = 1 x = 2

public static void main(String[] args) {

Pattern p = Pattern.compile("([a-z]+)(\\d+)");

Matcher m = p.matcher("aaa2223bb");

System.out.println(m.find()); // 返回 true 说明该正则匹配aaa2223

System.out.println(m.groupCount()); // 返回2,因为有2组

System.out.println(m.group(1)); // 返回aaa,返回第一组匹配到的子字符串

System.out.println(m.group(2)); // 返回2223,返回第二组匹配到的子字符串

//true

//2

//aaa

//2223

}

在给用户发送消息时通常情况会有相同的消息模板,但其中部分信息跟用户相关,因此需要对消息模板中的变量部分进行替换。而对于一个系统而言可能有很多套完全不同的模板。

public static String replacePlaceHolderWithMapValue(String msg,Map placeHolderMap) {

Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);

Matcher matcher = pattern.matcher(msg);

// 1、构建替换占位符实际值的Map

Map mapping = new HashMap<>();

while(matcher.find()) {

MatchResult matchResult = matcher.toMatchResult();

// 第一组匹配到 ${name} ${address}

String placeHolder = matchResult.group();

//第二组匹配到 name address

String key = matchResult.group(1);

Object value = placeHolderMap.get(key);

if(Objects.nonNull(value)) {

mapping.put(placeHolder,value.toString());

}

}

//2、做替换

for(Map.Entry entry:mapping.entrySet()) {

msg= msg.replace(entry.getKey(), entry.getValue());

}

return msg;

}

public static void main(String[] args) {

String msg = "${name} 项目发生外联,请注意此地址 ${address}";

Map placeHolderMap = new HashMap<>();

placeHolderMap.put("name","天河");

placeHolderMap.put("address","192.168.1.12");

String s = replacePlaceHolderWithMapValue(msg, placeHolderMap);

System.out.println(s); //天河 项目发生外联,请注意此地址 192.168.1.12

}

private static Matcher matcher(String str) {

Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);

Matcher matcher = pattern.matcher(str);

return matcher;

}

实例

public static final String EMAIL_PATTERN = "^[\\w!#$%&'*+/=?`{|}~^-]+(?:\\.[\\w!#$%&'*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,6}$";

public static final String CHINESE_PATTERN = "^[\u4e00-\u9fa5]{0,}$";

public static final String CONTAINS_CHINESE_PATTERN = "[\u4E00-\u9FA5|\\!|\\,|\\。|\\(|\\)|\\《|\\》|\\“|\\”|\\?|\\:|\\;|\\【|\\】]";

public static final String NUMBER_ADN_LETTER = "^[A-Za-z0-9]+$";

public static final String NUMBER_ADN_LETTER = "^[A-Za-z0-9]+$";

public static final String QQ_PATTERN = "/[1-9][0-9]{4,}/";

public static final String NUMBER_PATTERN = "[0-9]+";

public static final String LETTER_PATTERN = "[a-zA-Z]+";

public static final String ZIPCODE_PATTERN = "\\p{Digit}{6}";

public static final String PHONE_PATTERN = "^(13[0-9]|14[579]|15[^4,\\D]|16[6]|17[0135678]|18[0-9]|19[89])\\d{8}$";

public static final String TELEPHONE_PATTERN = "^(0\\d{2,3}-)?(\\d{7,8})(-(\\d{3,}))?$";

public static final String TELEPHONE_400_PATTERN = "((400)(\\d{7}))|((400)-(\\d{3})-(\\d{4}))";

public static final String IDCARD_PATTERN = "^((11|12|13|14|15|21|22|23|31"

+ "|32|33|34|35|36|37|41|42|43|44|45|46|50|51|"

+ "52|53|54|61|62|63|64|65|71|81|82|91)\\d{4})"

+ "((((19|20)(([02468][048])|([13579][26]))0229))|"

+ "((20[0-9][0-9])|(19[0-9][0-9]))((((0[1-9])|(1[0-2]))"

+ "((0[1-9])|(1\\d)|(2[0-8])))|((((0[1,3-9])"

+ "|(1[0-2]))(29|30))|(((0[13578])|(1[02]))31))))"

+ "((\\d{3}(x|X))|(\\d{4}))$";

public static final String USERNAME_PATTERN = "^[A-Za-z0-9_]{3,15}$";

public static final String PASSWORD_PATTERN = "^(?![0-9]+$)[0-9A-Za-z]{6,20}$";

public static final String UUID_PATTERN = "[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}";

public static final String YEAR_PATTERN = "^(19|20)\\d{2}$";

public static final String TIME_PATTERN = "^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$";

public static final String DATE_PATTERN = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))";

public static final String TIME_STAMP_PATTERN = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\s]?((((0?[13578])|(1[02]))[\\-\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\s]?((((0?[13578])|(1[02]))[\\-\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\s]?((0?[1-9])|(1[0-9])|(2[0-8])))))) ([2][0-3]|[0-1][0-9]|[1-9]):[0-5][0-9]:([0-5][0-9]|[6][0])$";

public static final String IPV4_PATTERN = "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])";

public static final String IPV6_PATTERN = "([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)\\:([0-9a-f]+)";

public static final String URL_PATTERN = "^(http|https|ftp)\\://([a-zA-Z0-9\\.\\-]+(\\:[a-zA-Z0-9\\.&%\\$\\-]+)*@)?((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\\-]+\\.)*[a-zA-Z0-9\\-]+\\.[a-zA-Z]{2,4})(\\:[0-9]+)?(/[^/][a-zA-Z0-9\\.\\,\\?\\'\\\\/\\+&%\\$#\\=~_\\-@]*)*$";

public static final String DOMAIN_PATTERN = "^(?=^.{3,255}$)[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+$";

public static final String INT_OR_FLOAT_PATTERN = "^\\d+\\.\\d+|\\d+$";

public static final String FLOAT_PATTERN = "^(-?\\d+)(\\.\\d+)?$";

public static final String POSITIVE_INTEGER = "[1-9]+\\d{0,10}";

public static final String GIT_URL_PATTERN = "(git@[\\w\\.]+)(:(//)?)([\\w\\.@\\:/\\-~]+)(\\.git)(/)?";

public static final String ARMY_ID_CARD = "南字第(\\d{6,8})号|北字第(\\d{6,8})号|沈字第(\\d{6,8})号|兰字第(\\d{6,8})号|成字第(\\d{6,8})号|济字第(\\d{6,8})号|广字第(\\d{6,8})号|海字第(\\d{6,8})号|空字第(\\d{6,8})号|参字第(\\d{6,8})号|政字第(\\d{6,8})号|后字第(\\d{6,8})号|装字第(\\d{6,8})号";

public static final String[] forbidden = {"\\bselect\\b", "\\bor\\b", "\\bdelete\\b", "\\bjoin\\b", "\\btable\\b"

, "\\bdrop\\b", "\\biframe\\b", "\\bwindow\\b", "\\b_\\b", "\\+", "%", "\\<", "\\>", "'", "=",

"%3C", "\\(", "%28", "alert", "eval((.*))", "script", "location.href"};

//匹配中括号

Pattern pattern = Pattern.compile("\\{\\{(.+?)}}");

推荐阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。