目录
定义
正则表达式定义了字符串的模式。正则表达式可以用来搜索、编辑或处理文本。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。Java的正则表示与Perl最为相似。在Java 1.4中对String类进行了扩展,提供了一个可以进行regex模式匹配的方法。
import java.util.regex.*;
1. 主要的3个类
- Pattern(模式) : Pattern类没有任何公共构造函数,我们使用它的公共静态方法compile()通过传递正则表达式参数来创建Pattern对象。
Pattern pattern = Pattern.compile(".xx.");
Pattern使用方法 : https://pingfangx.github.io/java-tutorials/essential/regex/pattern.html
- Matcher(匹配) : Matcher类没有任何公共构造函数,我们使用Pattern对象匹配方法得到一个Matcher对象,该方法将输入的字符串作为参数。然后我们使用matches()方法,根据输入的String是否与regex模式匹配,返回boolean结果。
Matcher matcher = pattern.matcher("MxxY");
Matcher使用方法 : https://pingfangx.github.io/java-tutorials/essential/regex/matcher.html
- PatternSyntaxException(语法不正确异常) : 正则表达式语法不正确则会抛出该异常。
// 错误语法用于测试异常
pattern = Pattern.compile("*xx*");
// 输出
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
*xx*
^
at java.util.regex.Pattern.error(Pattern.java:1924)
at java.util.regex.Pattern.sequence(Pattern.java:2090)
at java.util.regex.Pattern.expr(Pattern.java:1964)
at java.util.regex.Pattern.compile(Pattern.java:1665)
at java.util.regex.Pattern.(Pattern.java:1337)
at java.util.regex.Pattern.compile(Pattern.java:1022)
at com.journaldev.util.PatternExample.main(PatternExample.java:13)
PatternSyntaxException使用方法 : PatternSyntaxException 类的方法 | JAVA8 官网笔记教程
2. 使用正则表达式的两种办法
复杂模式: 可操作性更高,需要重复使用模式时使用。
import java.util.regex.*;
public class PatternExample {
public static void main(String[] args) {
Pattern pattern = Pattern.compile(".xx.");
Matcher matcher = pattern.matcher("MxxY");
System.out.println("Input String matches regex - "+matcher.matches());
}
}
简单模式 : 直接在String调用,简单的字符串匹配时使用,节省时间和代码行。
String str = "bbb";
System.out.println("Using String matches method: "+str.matches(".bb"));
System.out.println("Using Pattern matches method: "+Pattern.matches(".bb", str));
快速查找表
1. 匹配符号
符号 | 描述 | 例子 |
. | 匹配任何单一字符 | (“…”, “a%”) – true (“…”, “.a”) – true (“…”, “a”) – false |
^aaa | 匹配行首以aaa开头的字符串 | (“^a.c.”, “abcd”) – true (“^a”, “ac”) – false |
aaa$ | 匹配行末以aaa结尾的字符串 | (“…cd$”, “abcd”) – true (“a$”, “a”) – true (“a$”, “aca”) – false |
[abc] | 可以匹配任何一个字母a、b或c。 []被称为字符类。[]表示范围。 | (“^[abc]d.”, “ad9”) – true (“[ab].d$”, “bad”) – true (“[ab]x”, “cx”) – false |
[abc][12] | 可以与a、b或c相匹配,后面是1或2 | (“[ab][12].”, “a2#”) – true (“[ab]…[12]”, “acd2”) – true (“[ab][12]”, “c2”) – false |
[^abc] | 当^是[]中的第一个字符时,它否定了模式, 匹配除a、b或c之外的任何东西 | (“[^ab][^12].”, “c3#”) – true (“[^ab]…[^12]”, “xcd3”) – true (“[^ab][^12]”, “c2”) – false |
[a-e1-8] | 匹配a至e或1至8之间的范围 | (“[a-e1-3].”, “d#”) – true (“[a-e1-3]”, “2”) – true (“[a-e1-3]”, “f2”) – false |
xx yy | 匹配结果 xx 或 yy | 无 |
2. 元字符
常见的匹配模式中的元字符
原元字符 | 简略元字符 | 描述 |
[0-9] | \d | 任何数字 |
[^0-9] | \D | 任何非数字 |
[\t\n\x0B\f\r] | \s | 任何空白字符 |
[^/s] | \S | 任何非空格字符 |
[a-zA-Z_0-9] | \w | 任何单词字符 |
[^/w] | \W | 任何非文字的字符 |
无 | \b | 一个词的边界 |
无 | \B | 一个非词的边界 |
如何将表达式的字符(元字符)当做普通字符使用 :
1. 在元字符前加一个反斜杠(\)。
2. 将元字符保持在 \Q (开始引用)和 \E (结束引用)之内。
3. 量词
量词指定了要匹配的字符的出现次数。
元字符 | 描述 |
x? | x出现一次或0次(0/1次) |
X* | X出现0次或多次 |
X+ | X*出现一次或多次(至少出现一次) |
X{n} | X正好出现n次 |
X{n,} | X出现n或者比n更多的次数 |
X{n,m} | X出现的次数,在n次和m次之间,n和m包括 |
4. Groups组的使用
可以将多个元字符作为一个组使用,使用()创建一个组,使用双反斜杠+ 数字表明使用哪个组。
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false
上述第一行例子 : (\\w\\d)匹配"a2",(\\w\\d)为第一组表达式,\\1表示再使用一次第一组表达式,也就是"a2",最终加起来匹配到"a2a2"。第二行例子可以很好证明第一行中\\1的使用。
第三行例子 : (AB)为第一组表达式,匹配"AB"。(B\\d)为第二组表达式,匹配B+任意数字。\\2表示再使用一次第二组表达式,也就是(B\\d),匹配B+任意数字。\\1表示再使用一次第一组表达式,也就是(AB),匹配"AB"。用文字表达则是"AB+B+任意数字+B+任意数字+AB"。与matchs第二个参数内的String : "ABB2B2AB" 符合,返回true。第四行例子可以很好证明第三行。
5. 综合上表的快速查找表
表达式 | 描述 |
a-z | 表示小写字母a到z中任一个 |
A-Z | 表示大写字母A到Z中任一个 |
[xxx] | 表示xxx集合内的字符 |
[xxx]+ | 表示xxx集合内的字符,一个或更多个 |
常用应用实例(持续更新)
1. 表达式中与之匹配的常用方法例子
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexExamples {
public static void main(String[] args) {
// using pattern with flags
Pattern pattern = Pattern.compile("ab", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("ABcabdAb");
// using Matcher find(), group(), start() and end() methods
while (matcher.find()) {
System.out.println("Found the text \"" + matcher.group()
+ "\" starting at " + matcher.start()
+ " index and ending at index " + matcher.end());
}
// using Pattern split() method
pattern = Pattern.compile("\\W");
String[] words = pattern.split("one@two#three:four$five");
for (String s : words) {
System.out.println("Split using Pattern.split(): " + s);
}
// using Matcher.replaceFirst() and replaceAll() methods
pattern = Pattern.compile("1*2");
matcher = pattern.matcher("11234512678");
System.out.println("Using replaceAll: " + matcher.replaceAll("_"));
System.out.println("Using replaceFirst: " + matcher.replaceFirst("_"));
System.out.println(Pattern.quote("^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"));
}
}
2. 邮箱地址
package com.journaldev.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EmailValidator {
// Regex pattern to valid email address
private static final String EMAIL_REGEX="^[\\w-\\+]+(\\.[\\w]+)*@[\\w-]+(\\.[\\w]+)*(\\.[a-z]{2,})$";
//static Pattern object, since pattern is fixed
private static Pattern pattern;
//non-static Matcher object because it's created from the input String
private Matcher matcher;
public EmailValidator(){
//initialize the Pattern object
pattern = Pattern.compile(EMAIL_REGEX, Pattern.CASE_INSENSITIVE);
}
/**
* This method validates the input email address with EMAIL_REGEX pattern
* @param email
* @return boolean
*/
public boolean validateEmail(String email){
matcher = pattern.matcher(email);
return matcher.matches();
}
}
测试用例
package com.journaldev.regex;
public class EmailValidatorTest {
// list of valid email addresses
private static final String[] validEmailIds = new String[] { "journaldev@yahoo.com",
"journaldev-100@yahoo.com", "journaldev.100@yahoo.com",
"journaldev111@journaldev.com", "journaldev-100@journaldev.net",
"journaldev.100@journaldev.com.au", "journaldev@1.com",
"journaldev@gmail.com.com", "journaldev+100@gmail.com",
"journaldev-100@yahoo-test.com", "journaldev_100@yahoo-test.ABC.CoM" };
// list of invalid email addresses
private static final String[] invalidEmailIds = new String[] { "journaldev", "journaldev@.com.my",
"journaldev123@gmail.a", "journaldev123@.com", "journaldev123@.com.com",
".journaldev@journaldev.com", "journaldev()*@gmail.com", "journaldev@%*.com",
"journaldev..2002@gmail.com", "journaldev.@gmail.com",
"journaldev@journaldev@gmail.com", "journaldev@gmail.com.1a" };
private static EmailValidator emailValidator;
public static void main(String args[]){
emailValidator = new EmailValidator();
for (String temp : validEmailIds) {
boolean valid = emailValidator.validateEmail(temp);
System.out.println("Email ID "+temp+" is valid? " + valid);
}
System.out.println("\n\n");
for (String temp : invalidEmailIds) {
boolean valid = emailValidator.validateEmail(temp);
System.out.println("Email ID "+temp+" is valid? " + valid);
}
}
}
3. Pattern类实例
import java.util.regex.*;
public class PatternExample {
public static void main(String[] args) throws InterruptedException {
// Pattern pattern = Pattern.compile(".xx.");
// Matcher matcher = pattern.matcher("MxxY");
// System.out.println("Input String matches regex - "+matcher.matches());
// bad regular expression
//Thread.sleep(100);
//pattern = Pattern.compile("*xx*");
// String str = "bbb";
// System.out.println("Using String matches method: "+str.matches(".bb"));
// System.out.println("Using Pattern matches method: "+Pattern.matches(".bb", str));
// System.out.println(Pattern.matches("ad.$", "ade"));
// System.out.println(Pattern.matches("^d.", "ada"));
// System.out.println(Pattern.matches("d.", "da"));
// System.out.println(Pattern.matches("[ab]x", "cx"));
// System.out.println(Pattern.matches("^[abc]d.", "ad9"));
// System.out.println(Pattern.matches("[ab].d$", "bad"));
// System.out.println(Pattern.matches("[ab]x", "cx"));
// System.out.println(Pattern.matches("..", ".a"));
// System.out.println(Pattern.matches("[ab][12].", "a2#"));
// System.out.println(Pattern.matches("[ab]..[12]", "acd2"));
// System.out.println(Pattern.matches("[ab][12]", "c2"));
// System.out.println(Pattern.matches("[^ab][^12].", "c3#"));
// System.out.println(Pattern.matches("[^ab]..[^12]", "xcd3"));
// System.out.println(Pattern.matches("[^ab][^12]", "c2"));
// System.out.println(Pattern.matches("[a-e1-3].", "d#"));
// System.out.println(Pattern.matches("[a-e1-3]", "2"));
// System.out.println(Pattern.matches("[a-e1-3]", "f2"));
// System.out.println(Pattern.matches("x.|y", "xa"));
// System.out.println(Pattern.matches("x.|y", "y"));
// System.out.println(Pattern.matches("x.|y", "yz"));
// System.out.println(Pattern.matches("[a-zA-Z_0-9]", "9"));
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2a2")); //true
System.out.println(Pattern.matches("(\\w\\d)\\1", "a2b2")); //false
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B2AB")); //true
System.out.println(Pattern.matches("(AB)(B\\d)\\2\\1", "ABB2B3AB")); //false
}
}
4. 电话号码
public class PhoneNumberValidator {
public static void main(String[] args) {
System.out.println("Phone number 1234567890 validation result: "+validatePhoneNumber("1234567890"));
System.out.println("Phone number 123-456-7890 validation result: "+validatePhoneNumber("123-456-7890"));
System.out.println("Phone number 123-456-7890 x1234 validation result: "+validatePhoneNumber("123-456-7890 x1234"));
System.out.println("Phone number 123-456-7890 ext1234 validation result: "+validatePhoneNumber("123-456-7890 ext1234"));
System.out.println("Phone number (123)-456-7890 validation result: "+validatePhoneNumber("(123)-456-7890"));
System.out.println("Phone number 123.456.7890 validation result: "+validatePhoneNumber("123.456.7890"));
System.out.println("Phone number 123 456 7890 validation result: "+validatePhoneNumber("123 456 7890"));
}
private static boolean validatePhoneNumber(String phoneNo) {
//validate phone numbers of format "1234567890"
if (phoneNo.matches("\\d{10}")) return true;
//validating phone number with -, . or spaces
else if(phoneNo.matches("\\d{3}[-\\.\\s]\\d{3}[-\\.\\s]\\d{4}")) return true;
//validating phone number with extension length from 3 to 5
else if(phoneNo.matches("\\d{3}-\\d{3}-\\d{4}\\s(x|(ext))\\d{3,5}")) return true;
//validating phone number where area code is in braces ()
else if(phoneNo.matches("\\(\\d{3}\\)-\\d{3}-\\d{4}")) return true;
//return false if nothing matches the input
else return false;
}
}
参考文章 :
1. Regular Expression in Java - Java Regex Example | DigitalOcean