【软件构造】正则表达式



【软件构造】正则表达式


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);
    }

}

使用两个串str1str2匹配表达式,

Pattern re=Pattern.compile("http://([a-z]+\\.)+[a-z]+(:[0-9]+)?/");

需要注意的是 \\. 匹配的是  ,结果如下:

具体匹配过程实际上就是《形式语言与自动机》中所讲述的语法树的派生与归约过程,具体分析见下节。


4.语法派生树

本节我们采取一个较为复杂的例子进行描述,即正则表达式为:

url ::= 'http://' hostname '/' 
hostname ::= word '.' word 
word ::= [a-z]+

其采取栈结构,派生 http://mit.edu/ 过程如下:

  1. 初始,栈中只有url
  2. 弹出url,压入 http:// hostname/ 其中  http://  处于栈顶
  3. 弹出栈顶 http://,由于是终结符,直接匹配
  4. 弹出hostname ,压入word . word 
  5. 弹出word,压入mit(由[a-z]+派生出)
  6. 逐次弹出 mit,由于是终结符,直接匹配
  7. 弹出 ,由于是终结符,直接匹配 
  8. 弹出word,压入edu(由[a-z]+派生出)
  9. 逐次弹出 edu,由于是终结符,直接匹配
  10. 弹出栈顶 /,由于是终结符,直接匹配

由此,派生出  http://mit.edu/  ,其对应派生树如下:


Ending~??