正则表达式
是一种字符串的语法规则,是一种可以用于模式匹配和替换的规则,主要用于文本和字符串的处理。
一个正则表达式是由普通字符和特殊字符(元字符)组成的文字模式,用以描述在查找文字主体时待匹配的一个或多个字符串。
元字符
正则表达式由一些具有特殊意义的字符组成的字符串,这些具有特殊意义的字符称为元字符。
元字符 | 正则表达式中的写法 | 意义 |
---|---|---|
. | . | 任何一个字符 |
\d | \\d | 0~9的任何一个数字 |
\D | \\D | 任何一个非数字字符 |
\s | \\s | 空格类字符,’\t’,’\n’,’\f’,’\r’,’\x0B’ |
\S | \\S | 非空格类字符 |
\w | \\w | 可用于标识符的字符(不包含美元符号) |
\w | \\W | 不能用于标识符的字符 |
\p{Lower} | \\p{Lower} | 小写字母 |
\p{Upper} | \\p{Upper} | 大写字母 |
\p{ASCll} | \\p{ASCll} | ASCll字符 |
\p{Alpha} | \\p{Alpha} | 字母 |
\p{digit} | \\p{digit} | 数字字符 |
\p{Alnum} | \\p{Alnum} | 字母或数字 |
\p{Punct} | \\p{Punct} | 标点符号 |
\p{greph} | \\p{greph} | 可视字符\p{Alnum}\p{Punct} |
\p{Print} | \\p{Print} | 可打印字符,\p{graph} |
\p{Blank} | \\p{Blank} | 空格或制表符 |
\p{Cntrl} | \\p{Cntrl} | 控制字符[\x00-\x1F\x7F] |
实例:判断给定字符串是否合法,合法字符串:大写字母+3个小写字母+3个数组
public class StringMatch {
public static void main(String[] args) {
String regex="\\p{Upper}\\p{Lower}\\p{Lower}\\p{Lower}\\d\\d\\d";
String message1="AXDd001";
String message2="Abcd001";
boolean result1=message1.matches(regex);
boolean result2=message2.matches(regex);
if(result1)
System.out.println(message1+"是合法数据");
else System.out.println(message1+"不是合法数据");
if(result2)
System.out.println(message2+"是合法数据");
else System.out.println(message2+"不是合法数据");
}
}
正则表达式中的[ ]
元字符既可以是放在[ ]中的任意单个字符([a]表示匹配单个小写字母a)
也可以是字符序列([a-d]表示匹配a、b、c、d之间的任意一个字符,而\w表示任意英文字母和数字及下划线)。
正则表达式中的限定符
使用正则表达式时,如果需要某一类型的元字符多次输出,逐个输入相当麻烦,这时可以使用正则表达式的限定元字符来重复输出。
带限定符号的模式 | 含义 |
---|---|
X? | X出现0次或1次 |
X* | X出现0次或多次 |
X+ | X出现1次或多次 |
X{n} | X出现n次 |
X{n,} | X至少出现n次 |
X{n,m} | X出现n至m次 |
XY | X后跟Y |
实例:判断用户输入是否合法的手机号码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PhoneValidation {
public static void main(String[] args) throws IOException {
boolean contiGo=true;
BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
String regex="(13\\d|15[036-9]|18[689])\\d{8}";
String phoneNumber="";
while(contiGo) {
System.out.println("请输入手机号码:");
phoneNumber=buf.readLine();
boolean match=phoneNumber.matches(regex);
if(match) {
System.out.println(phoneNumber+"是合法手机号");
break;
}else
System.out.println(phoneNumber+"不是合法手机号");
}
}
}
Java从JDK1.4开始增加了对正则表达式的支持
由java.util.regex包提供。主要包括三个类:
- Pattern类:
pattern对象是一个正则表达式的编译表示。该类无公共构造方法。要创建一个Pattern对象,必须先调用其公共静态编译方法,它返回一个Pattern对象。该方法接收一个正则表达式作为它的第一个参数。 - Matcher类:
Matcher对象是对输入字符串进行解释和匹配操作的引擎。无公共构造方法,需要调用Pattern对象的matcher方法来获得一个Matcher对象。 - PatternSyntaxException:
非强制异常类,它表示一个正则表达式模式中的语法错误。
import java.util.regex.Pattern;
public class RegexExample1 {
public static void main(String[] args) {
String content="I am coder"+
"from nowcoder.com";
String pattern=".*nowcoder.*";
boolean isMatch=Pattern.matches(pattern, content);
System.out.println("字符串中是否包含了'nowcoder'子字符串?"+isMatch);
}
}
捕获组
概念:
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
可以通过调用matcher对象的groupCount方法来查看表达式有多少个分组。groupCount方法返回一个int值,表示matcher对象当前有多个捕获组。
特殊的组(group(0)):代表整个表达式。该组不包括在groupCount的返回值中。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PRegexMatches {
public static void main(String[] args) {
String line="This order was placed for QT3000!OK?";
String pattern="(\\D*)(\\d+)(.*)";
Pattern r=Pattern.compile(pattern);
Matcher m=r.matcher(line);
if(m.find()) {
System.out.println("Found value:"+m.group(0));
System.out.println("Found value: " + m.group(1) );
System.out.println("Found value: " + m.group(2) );
System.out.println("Found value: " + m.group(3) );
}else {
System.out.println("NO MATCH");
}
}
}
Pattern类的方法
compile 方法
编译一个正则表达式并返回一个编译好的pattern对象
Pattern patt =Pattern.compile("[a-z[1-9]]{1,9});
matcher方法
Pattern的matcher方法用于封装一个要操作的字符串并返回Matcher对象,用于操作字符串
Matcher matcher = patt.matcher("xzc");
Matcher类的方法
matches方法
Matcher类的matches方法用判断字符串和正则表达式是否匹配。
if(matcher.matches())
System.out.println("匹配");
else
System.out.println("不匹配");
索引方法
索引方法提供了有用的索引值,精确表明输入字符串中在哪能找到匹配。
方法 | 说明 |
---|---|
public int start() | 返回以前匹配的初始索引 |
public int start(int group) | 返回在以前的匹配操作期间,由定组所捕获的子序列的初始索引 |
public int end() | 返回最后匹配字符之后的偏移量 |
public int end(int group) | 返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量 |
研究方法
用来检查输入字符串并返回一个布尔值,表示是否找到该模式。
方法 | 说明 |
---|---|
public boolean lookingAt() | 尝试将从区域开头开始的输入序列与1该模式匹配 |
public boolean find() | 尝试查找与该模式匹配的输入序列的下一个子序列 |
public boolean find(int start) | 重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。 |
public boolean matches() | 尝试将整个区域与模式匹配。 |
替换方法
替换输入字符串里的文本的方法:
方法 | 说明 |
---|---|
public Matcher appendReplacement(StringBuffer sb, String replacement) | 实现非终端添加和替换步骤。 |
public StringBuffer appendTail(StringBuffer sb) | 实现终端添加和替换步骤 |
public String replaceAll(String replacement) | 替换模式与给定替换字符串相匹配的输入序列的每个子序列。 |
public String replaceFirst(String replacement) | 替换模式与给定替换字符串匹配的输入序列的第一个子序列。 |
public static String quoteReplacement(String s) | 返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement 方法一个字面字符串一样工作 |
start和end方法
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
private static final String REGEX="\\bcat\\b";
private static final String INPUT="cat cat cat cattie cat";
public static void main(String[] args) {
Pattern p=Pattern.compile(REGEX);
Matcher m=p.matcher(INPUT);//封装要操作的字符串并返回Matcher对象,用于操作字符串
int count=0;
while(m.find()) {
count++;
System.out.println("Match number "+count);
System.out.println("start():"+m.start());
System.out.println("end()"+m.end());
}
}
}
matches和lookingAt方法
都是尝试匹配一个输入序列模式
matches要求整个序列都匹配;lookingAt不要求;
lookingAt方法虽然不需要整句都匹配,但是需要从第一个字符开始匹配。这两种方法经常在输入字符串的开始使用。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
private static final String REGEX="foo";
private static final String INPUT="fooooooooooooooooo";
private static final String INPUT2="ooooofoooooooooooo";
private static Pattern pattern;
private static Matcher matcher;
private static Matcher matcher2;
public static void main(String[] args) {
pattern=Pattern.compile(REGEX);
matcher=pattern.matcher(INPUT);
matcher2=pattern.matcher(INPUT2);
System.out.println("Current REGEX is:"+REGEX);
System.out.println("Current INPUT is: "+INPUT);
System.out.println("Current INPUT2 is: "+INPUT2);
System.out.println("lookingAt(): "+matcher.lookingAt());
System.out.println("matches(): "+matcher.matches());
System.out.println("lookingAt(): "+matcher2.lookingAt());
}
}
输出;
Current REGEX is:foo
Current INPUT is: fooooooooooooooooo
Current INPUT2 is: ooooofoooooooooooo
lookingAt(): true
matches(): false
lookingAt(): false
//matcher2开头的字母不是我们要找的字母,所以返回了false
replaceFirst和replaceAl方法
这两种方法用来替换正则表达式的文本。不同的是,replaceFirst替换首次匹配,replaceAll替换所有匹配。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
private static String REGEX="dog";
private static String INPUT="The dog says meow."+
"All dogs say meow.";
private static String REPLACE="cat";
public static void main(String[] args) {
Pattern p=Pattern.compile(REGEX);
Matcher m=p.matcher(INPUT);
INPUT=m.replaceAll(REPLACE);
System.out.println(INPUT);
INPUT=m.replaceFirst(REPLACE);
System.out.println(INPUT);
}
}
appendReplacement和appendTail方法
用于文本交换
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
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 m=p.matcher(INPUT);
StringBuffer sb=new StringBuffer();
while(m.find()) {
m.appendReplacement(sb, REPLACE);
}
m.appendTail(sb);
System.out.println(sb.toString());
}
}
PatternSynataxExceprtion类
非强制异常类,指示一个正则表达式模式中的语法错误
方法 | 说明 |
---|---|
public String getDescription() | 获取错误的描述 |
public int getIndex() | 获取错误的下标 |
public String getPattern() | 获取错误的正则表达式模式 |
public String getMessage() | 返回多行字符串,包含语法错误及其索引的描述、错误的正则表达式模式和模式中错误索引的可视化指示 |