1 正则表达式
1 最基础:
要找一个数字,它可能有一个负号在前面,那么就写上一个负号加上一个问号: -?
在JAVA中,\\的意思是“我要插入一个正则表达式的反斜线,表示其后的字符具有特殊的意义”,所以要描述一个整数,正则表达式应该是: \\d。同理,要插入一个普通的反斜线,则应该是:\\\\。
要表示“一个或多个之前的表达式”,应该使用:+
综上,要表示“可能有一个负号,后面跟着一位或多位数字”,可以这样: -?\\d+.
使用正则表达式的最简单途径——String类的内建功能:
匹配:“-1234”.matches("-?\\d+");
切分:split()方法,将字符串从正则表达式匹配的地方切开。string.split("n\\W+"); 表示字母n后面跟着一个或多个非单词字符。被匹配的字符串是不出现在切分结果中的。
替换:替换正则表达式第一个匹配的子串,或是替换所有匹配的地方。 s.replaceFirst("f\\w+", "located"); s.replaceAll(“shrubbery|tree|herring”, "banana");
如果正则表达式不是只使用一次的话,非String对象的正则表达式明显具备更佳的性能。这个在稍后就会看到。
例:下面的每一个正则表达式都能成功匹配字符序列“Rudolph”
for(String pattern: new String[]{
"Rudolph", "[rR]udolph", "[rR][aeiou][a-z].*", "R.*" })
})
System.out.println("Rudolph".matched(pattern));
2 量词
量词描述了一个模式吸收输入文本的方式
- 贪婪型:为所有可能的模式发现极可能多的匹配
- 勉强型:匹配满足模式所需要的最少字符数
- 占有型:只能用于Java。
import java.util.regex.*;
public class testRegex
{
public static String t = "Java now has regular expressions";
public static String r = "((^[aeious])|(\s+[aeiou]))"
{
System.out.println("Input: \"" + args[0] + "\"");
for(String arg: args)
{
System.out.println("Regular expression: \"" + arg + "\"");
Pattern p = Pattern.compile(arg);
Matcher m = p.matcher(t);
while(m.find())
{
System.out.println("Match \"" + m.group() + "\" at position" + m.start() + "-" + (m.end()-1));
}
}
}
}
- 导入java.util.regex包,然后用static Pattern.compile()方法编译你的正则表达式,生成一个Pattern对象
- 把要检索的字符串传入Pattern对象的matcher()方法,matcher方法会生成一个Matcher对象,该对象有很多方法,如
- boolean matches():匹配整个输入的字符串是否匹配正则表达式
- bollean lookingAt():判断该字符串(不必是整个字符串)的某一部分是否能够匹配模式。
- bollean find():在字符串中查找多个匹配,用Matcher.group()返回查找到的匹配的字符串。
- boolean find(int start)
2 正题——语法分析
2.1 词法分析器实现正则表达式
expr = ab(c|d)e
可以用附加定义重写:aux = c d
expr = a b aux e
为了避免使用交替符号,对于同一符号,可以使用一些辅助扩充:
aux = c
aux = d
expr = a b aux e
另外一个i例子:
expr = (a b c)*
expr = (a b c)expr
expr = &
2.2 上下文无关文法CFG
对于语法分析,字符串就是源程序,符号就是词法记号,字母表就是词法分析器返回的记号类型集。
推导:从开始符号出发,对于任一非终结符,用其产生式的右侧部分进行替换并重复进行这一操作。
2.3 分析树
2.4 预测分析——递归下降分析
- 每一个非终结符定义成一个递归函数
- 每一个右部写成函数的一个分情况讨论