下午面试遇到一道笔试题,题目是编写一个支持部分正则表达式的解析器,获取目标字符串在原字符串中第一次出现的索引,例如 查找“ava”在“Lear Java.”中第一次出现的索引为6
其中“.”代表任意单个字符,“^”代表从字符串的开头开始匹配,“$”匹配字符串的结尾,“*”匹配任意个字符
因为在其他笔试题中浪费了太多时间,没有写出这部分代码,回家路上有了思路,现在记录下来。
/**
* 主要的工具类
* Created by Morven on 2017/5/18.
*/
public class RegularMacher {
private RegularMacher() {}
private static class RegularMacherHolder {
private static RegularMacher instance = new RegularMacher();
}
public static RegularMacher getInstance() {
return RegularMacherHolder.instance;
}
public int matchIndex(String source, String regular) {
char[] chars = regular.toCharArray();
for (int i = 0; i < source.length(); i++) {
int index = indexOf(source, i, chars, 0);
if (index > -1) return index;
}
return -1;
}
private int indexOf(String source, int beginIndex, char[] chars, int charIndex) {
char c = chars[charIndex];
if (c == '^') {
if (beginIndex > 0) {
return -1;
}
int index = indexOf(source, beginIndex, chars, charIndex + 1);
if (index > -1) {
return beginIndex;
}
return -1;
} else if (c == '$') {
if (beginIndex < source.length()) {
return -1;
}
return beginIndex;
} else if (c == '.') {
} else if (c == '*') {
if (charIndex + 1 == chars.length) {
return beginIndex;
}
if (charIndex + 2 == chars.length && chars[charIndex + 1] == '$') {
return beginIndex;
}
for (int i = beginIndex; i < source.length(); i++) {
int index = indexOf(source, i, chars, charIndex + 1);
if (index > -1) return index;
}
return -1;
} else {
if (c != source.charAt(beginIndex)) {
return -1;
}
}
if (charIndex + 1 == chars.length) return beginIndex;
if (beginIndex + 1 == source.length()) {
if (charIndex + 2 < chars.length) return -1;
}
int index = indexOf(source, beginIndex + 1, chars, charIndex + 1);
if (index > -1) {
return beginIndex;
}
return -1;
}
}
/**
* 测试
* Created by Morven on 2017/5/18.
*/
public class RegularMacherTest {
public static void main(String[] args) {
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", ".est"));//0
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", ".ssdfa"));//-1
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", "^.aa"));//-1
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", "*"));//0
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", "*$"));//0
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", "j*i"));//5
System.out.println(RegularMacher.getInstance().matchIndex("Test java in Action.", "j*ava"));//5
}
}