1.元字符
1.转义号
\ \符号是转义符号,在使用正则表达式去检索某些特殊的字符时使用。否则会检索不到结果或报错。
比如匹配(时应该使用
String reg="\\(";
为匹配串。
常见的需要用到转义符的字符如下:
. * + ( ) $ / \ ? [ ] ^ { }
2.字符匹配符
符号 | 作用 | 示例 | 解释 |
---|---|---|---|
[ ] | 可接受的字符列表 | [123] | 匹配1,2,3中的任意一个字符 |
[^] | 不可接受的字符列表 | [^123] | 除了1,2,3之外的所有字符包括特殊符号 |
- | 连字符 | a-z | a到z之间的单个小写字母 |
. | 匹配除了\n之外的任何字符 | a…b | 以a开头,b结尾,中间包含2个任意字符的长度为4的字符串(acdb,a#\b等) |
\\d | 匹配单个数字字符,相当于[0-9] | \\d{3}(\\d)? | 包括3个或4个数字的字符串(123,2341等) |
\\D | 匹配单个非数字字符相当于[^0-9] | \\D(\\d)* | 以单个非数字字符开头,后接任意个数字字符串(\123,a) |
\\w | 匹配单个数字,大小写字母字符,相当于[0-9a-zA-Z] | \\d{3}\w{4} | 以3个数字字符开头后接4个数字和字母的混合字符串(123q123) |
\\W | 匹配单个除了数字大小写字符以外的字符,相当于[^0-9a-zA-Z] | \\W+\\d{2} | 已至少一个非数字字母字符开头,2个数字字符结尾的字符串 |
java的正则表达式默认是区分字母大小写的,若想实现不区分大小写,有如下方法:
(?i)abc 表示abc都不区分大小写
a(?i)bc 表示只有bc不区分大小写
a((?i)b)c 表示只有b不区分大小写
Pattern pat=Pattern.compile(reg,Pattern.CASE_INSENSITIVE); 创建Pattern对象时,指定参数Pattern.CASE_INSENSITIVE表示不区分大小写
3.选择匹配符
在匹配某个字符串时是有选择性的,即或的关系,此时需要使用符号 | 。匹配“|”左右的表达式,比如ab|cd代表匹配ab或者cd
4.限定符
符号 | 含义 | 举例 | 解释 |
---|---|---|---|
* | 指定字符重复0次或n次 | (abc)* | 包含任意个abc(空串,abcabc) |
+ | 指定字符重复正整数次 | m+(abc)+ | 以至少一个m开头,后面接任意个abc字符串(m,mabc) |
? | 指定字符至多出现一次,?生效的范围是最近的字符 | m+abc? | 以至少一个m开头,后接ab或abc字符串 |
{n,} | 指定至少n个匹配 | [abc]{3,} | 由a,b,c组成的任意长度至少为3的字符串 |
{n} | 只能输入n个字符串 | [abc]{3} | 由a,b,c组成的任意长度为3的字符串 |
{n,m} | 指定至少n个,但不多于m个匹配 | [abc]{3,5} | 由a,b,c组成的任意长度在区间[3,5]的字符串 |
贪婪匹配:上述表格中范围的优先匹配数量最多的。要是非贪婪匹配只需在(* + ? {n} {n,} {n,m})后加上?比如o+?表示只匹配一个o
5.定位符
规定要匹配的字符串出现的位置,比如是在开始还是在结束
符号 | 含义 | 举例 | 解释 |
---|---|---|---|
^ | 指定起始字符 | 1+[a-z]* | 以至少1个数字开头,后接任意个小写字母的字符串 |
$ | 指定结束字符 | 2\\-[a-z]+$ | 以1个数字开头后接连接符“-”,并以至少一个小写字母结尾的字符串 |
\\b | 匹配目标字符串的边界 | han\\b | 这里说的字符串的边界是指子串见有空格,或者是目标字符串的结束位置(hanshunpinghan hanhan) |
\\B | 匹配目标字符串的非边界 | han\\B | 和\\b的含义刚刚相反 |
2.捕获分组
常见分组构造形式 | 说明 |
---|---|
(pattern) | 非命名捕获。捕获匹配的字符串。编号为0的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号 |
(?<name>pattern) | 命名捕获。将匹配的子字符串捕获到一个组名或编号名称中。用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号(?‘name’) |
3.简单使用
文本:
代码:
public static void readFromText(String fileName) throws IOException {
//1.先将上述文本信息从txt文件中读出
ArrayList<String> s=new ArrayList<String>();
File file=new File(fileName);
InputStreamReader input=new InputStreamReader(new FileInputStream(file));
BufferedReader bf=new BufferedReader(input);//按行读入
String line;
while((line=bf.readLine())!=null)
{
s.add(line);
}
bf.close();
input.close();
String context=String.valueOf(s);//读出的结果
/*匹配Period,可以发现所有文件的Period都是这种格式Period{4位数字-2位数字-2位数字, 4位数字-2位数字-2位数字}
所以,采用了如下正则匹配串匹配文本*/
String reg1="Period\\{(\\d{4})\\-(\\d{2})-(\\d{2}),(\\d{4})\\-(\\d{2})\\-(\\d{2})\\}";
Pattern pattern1=Pattern.compile(reg1);
Matcher matcher1=pattern1.matcher(context);
long syear=0;
int smonth = 0;
int sday=0;
long eyear=0;
int emonth=0;
int eday=0;
while(matcher1.find())
{
syear=Integer.valueOf(matcher1.group(1)).longValue();
smonth=Integer.valueOf(matcher1.group(2)).intValue();
sday=Integer.valueOf(matcher1.group(3)).intValue();
eyear=Integer.valueOf(matcher1.group(4)).longValue();
emonth=Integer.valueOf(matcher1.group(5)).intValue();
eday=Integer.valueOf(matcher1.group(6)).intValue();
}
/*匹配Employee2. 对Employee的解析,可以发现所有文件的Employee里面的文本信息都是这种格式(至少1个字母部分含有数字,且字母区分大小写){(区分大小写的字母部分含有空格),(若干位由数字和-连接而成的串) }
所以,采用了如下正则匹配串匹配文本*/
String reg2="([A-Za-z0-9]+)\\{([A-Za-z ]+),([0-9]{3}\\-[0-9]{4}\\-[0-9]{4})\\}";
Pattern pattern2=Pattern.compile(reg2);
Matcher matcher2=pattern2.matcher(context);
while(matcher2.find())
{
for(int i=1;i<matcher2.groupCount();i+=3)
{
Employee e=new Employee(matcher2.group(i),matcher2.group(i+1), matcher2.group(i+2));
}
}
/*匹配Roster,对Roster的解析,可以发现所有文件的Roster里面的文本信息都是这种格式(至少1个字母部分含有数字,且字母区分大小写){4位数字-2位数字-2位数字, 4位数字-2位数字-2位数字},但这个格式和上面的Period的格式类似,为了避免把Period读入,再加上判断,把Period对象给滤过掉。
所以,采用了如下正则匹配串匹配文本*/
String reg3="([A-Za-z]+)\\{(\\d{4})\\-(\\d{2})\\-(\\d{2}),(\\d{4})\\-(\\d{2})\\-(\\d{2})\\}";
Pattern pattern3=Pattern.compile(reg3);
Matcher matcher3=pattern3.matcher(context);
while(matcher3.find())
{
String name=matcher3.group(1);
if(!name.equals("Period"))
{syear=Integer.valueOf(matcher3.group(2)).longValue();
smonth=Integer.valueOf(matcher3.group(3)).intValue();
sday=Integer.valueOf(matcher3.group(4)).intValue();
eyear=Integer.valueOf(matcher3.group(5)).longValue();
emonth=Integer.valueOf(matcher3.group(6)).intValue();
eday=Integer.valueOf(matcher3.group(7)).intValue();
}
}
//打印结果
dutyIntervalSet.Display();
}
打印的结果如下: