【软件构造】正则表达式
【软件构造】正则表达式
1.定义
正则表达式:用来匹配一系列符合某个语法规则的字符串。
2.语法规则
2.1 基本符号
符号 | 功能描述 | 示例 |
. | 匹配除换行符以外的所有字符 | w.h可以匹配wah,wbh,w#h等 |
[ ] | 匹配方括号里的任意单个字符 | w[abc]h匹配wah,wbh,wch |
| | 或运算,选择其中一项匹配 | w(a|bb|ccc)h匹配wah,wbbh.wccch |
^ | 否的意思 | [^a]表示除了a的字符 |
\w | 匹配所有字母数字 | [0-9A-Z_a-z] |
\W | 匹配所有非字母数字 | [^\w] |
\d | 匹配数字 | [0-9] |
\D | 匹配非数字 | [^\d] |
\s | 匹配所有空格字符 | [\t\n\f\r] |
\S | 匹配所有非空格字符 | [^\s] |
2.2 匹配次数符号
符号 | 功能描述 |
* | ≥0次 |
+ | ≥1次 |
? | 0次或1次 |
{n} | n次 |
{m,n} | m次到n次 |
示例:[0-9]{ 3 } \- [0-9]{ 3 } \- [0-9]{ 4 }匹配:123-456-7890,012-345-6789等。
3.在Java中的应用
可以根据给定的正则表达式,生成相应的语法库,检验给定字符串是否合法。
给出程序示例如下:
package Test;
/*
@author HIT_Why 120L021418
*/
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularExp {
public static void main(String[] args) {
Pattern re=Pattern.compile("http://([a-z]+\\.)+[a-z]+(:[0-9]+)?/");
String str1=new String("http://hit.cs.why/");
String str2=new String("http://hit.cs.why:2003002/");
System.out.println(str1);
System.out.println(str2);
Matcher m1=re.matcher(str1);
Matcher m2=re.matcher(str2);
System.out.println("m1? "+m1.matches());
System.out.println("m1: "+m1);
System.out.println("m2? "+m2.matches());
System.out.println("m2: "+m2);
}
}
使用两个串str1,str2匹配表达式,
Pattern re=Pattern.compile("http://([a-z]+\\.)+[a-z]+(:[0-9]+)?/");
需要注意的是 \\. 匹配的是 . ,结果如下:
具体匹配过程实际上就是《形式语言与自动机》中所讲述的语法树的派生与归约过程,具体分析见下节。
4.语法派生树
本节我们采取一个较为复杂的例子进行描述,即正则表达式为:
url ::= 'http://' hostname '/'
hostname ::= word '.' word
word ::= [a-z]+
其采取栈结构,派生 http://mit.edu/ 过程如下:
- 初始,栈中只有url
- 弹出url,压入 http:// ,hostname, / ,其中 http:// 处于栈顶
- 弹出栈顶 http://,由于是终结符,直接匹配
- 弹出hostname ,压入word . word
- 弹出word,压入mit(由[a-z]+派生出)
- 逐次弹出 mit,由于是终结符,直接匹配
- 弹出 . ,由于是终结符,直接匹配
- 弹出word,压入edu(由[a-z]+派生出)
- 逐次弹出 edu,由于是终结符,直接匹配
- 弹出栈顶 /,由于是终结符,直接匹配
由此,派生出 http://mit.edu/ ,其对应派生树如下:
Ending~??