提交 02822715 编写于 作者: xindoo's avatar xindoo

refactor codes

上级 25fb0571
package xyz.xindoo.re;
public interface Constant {
String EPSILON = "Epsilon";
String CHAR = "char";
String CHARSET = "charSet";
}
package xyz.xindoo.re;
import xyz.xindoo.re.nfa.strategy.CharMatchStrategy;
import xyz.xindoo.re.nfa.strategy.CharSetMatchStrategy;
import xyz.xindoo.re.nfa.strategy.DigitalMatchStrategy;
import xyz.xindoo.re.nfa.strategy.DotMatchStrategy;
import xyz.xindoo.re.nfa.strategy.EpsilonMatchStrategy;
import xyz.xindoo.re.nfa.NFAGraph;
import xyz.xindoo.re.nfa.strategy.MatchStrategy;
import xyz.xindoo.re.nfa.strategy.SpaceMatchStrategy;
import xyz.xindoo.re.nfa.strategy.WMatchStrategy;
import xyz.xindoo.re.nfa.strategy.MatchStrategyManager;
import java.util.List;
import java.util.Map;
......@@ -33,7 +28,7 @@ public class Regex {
NFAGraph NFAGraph = null;
while (reader.hasNext()) {
char ch = reader.next();
MatchStrategy matchStrategy = null;
String edge = null;
switch (ch) {
// 子表达式特殊处理
case '(' : {
......@@ -59,7 +54,7 @@ public class Regex {
break;
}
case '[' : {
matchStrategy = getCharSetMatch(reader);
edge = getCharSetMatch(reader);
break;
}
case '^' : {
......@@ -69,7 +64,7 @@ public class Regex {
break;
}
case '.' : {
matchStrategy = new DotMatchStrategy();
edge = ".";
break;
}
// 处理特殊占位符
......@@ -77,32 +72,32 @@ public class Regex {
char nextCh = reader.next();
switch (nextCh) {
case 'd': {
matchStrategy = new DigitalMatchStrategy(false);
edge = "\\d";
break;
}
case 'D': {
matchStrategy = new DigitalMatchStrategy(true);
edge = "\\D";
break;
}
case 'w': {
matchStrategy = new WMatchStrategy(false);
edge = "\\w";
break;
}
case 'W': {
matchStrategy = new WMatchStrategy(true);
edge = "\\W";
break;
}
case 's': {
matchStrategy = new SpaceMatchStrategy(false);
edge = "\\s";
break;
}
case 'S': {
matchStrategy = new SpaceMatchStrategy(true);
edge = "\\S";
break;
}
// 转义后的字符匹配
default:{
matchStrategy = new CharMatchStrategy(nextCh);
edge = String.valueOf(nextCh);
break;
}
}
......@@ -110,23 +105,20 @@ public class Regex {
}
default : { // 处理普通字符
matchStrategy = new CharMatchStrategy(ch);
edge = String.valueOf(ch);
break;
}
}
// 表明有某类单字符的匹配
if (matchStrategy != null) {
State start = new State();
State end = new State();
start.addNext(matchStrategy, end);
NFAGraph newNFAGraph = new NFAGraph(start, end);
checkRepeat(reader, newNFAGraph);
if (NFAGraph == null) {
NFAGraph = newNFAGraph;
} else {
NFAGraph.addSeriesGraph(newNFAGraph);
}
State start = new State();
State end = new State();
start.addNext(edge, end);
NFAGraph newNFAGraph = new NFAGraph(start, end);
checkRepeat(reader, newNFAGraph);
if (NFAGraph == null) {
NFAGraph = newNFAGraph;
} else {
NFAGraph.addSeriesGraph(newNFAGraph);
}
}
return NFAGraph;
......@@ -168,8 +160,9 @@ public class Regex {
return false;
}
for (Map.Entry<MatchStrategy, List<State>> entry : curState.next.entrySet()) {
MatchStrategy matchStrategy = entry.getKey();
for (Map.Entry<String, List<State>> entry : curState.next.entrySet()) {
String edge = entry.getKey();
MatchStrategy matchStrategy = MatchStrategyManager.getStrategy(edge);
if (matchStrategy instanceof EpsilonMatchStrategy) {
for (State nextState : entry.getValue()) {
if (isMatch(text, pos, nextState)) {
......@@ -177,7 +170,7 @@ public class Regex {
}
}
} else {
if (!matchStrategy.isMatch(text.charAt(pos))) {
if (!matchStrategy.isMatch(text.charAt(pos), edge)) {
continue;
}
// 遍历匹配策略
......@@ -194,17 +187,12 @@ public class Regex {
/**
* 暂时只支持字母 数字
* */
static CharSetMatchStrategy getCharSetMatch(Reader reader) {
static String getCharSetMatch(Reader reader) {
String charSet = "";
boolean isReverse = false;
char ch;
while ((ch = reader.next()) != ']') {
if (ch == '^') {
isReverse = true;
continue;
}
charSet += ch;
}
return new CharSetMatchStrategy(charSet, isReverse);
return charSet;
}
}
......@@ -5,16 +5,14 @@ import java.util.List;
public class RegexTest {
public static void main(String[] args) throws Exception {
Regex regex = Regex.compile("a.+b");
Regex regex = Regex.compile("a\\s?.+b");
System.out.println(regex.isMatch("abb"));
System.out.println(regex.isMatch("a1123b"));
System.out.println(regex.isMatch("abcccd"));
System.out.println(regex.isMatch("a 1123b"));
System.out.println(regex.isMatch("a bcccd"));
System.out.println(regex.isMatch("ad"));
System.out.println(regex.isMatch("abcd"));
System.out.println(regex.isMatch("a3abcd"));
System.out.println(regex.isMatch("a33333defd"));
System.out.println(regex.isMatch("aabcabcabcabcabcabcdb"));
// List<String> res = regex.match("abcdefgaabcdadefd");
// System.out.println(res.size());
}
}
......@@ -16,13 +16,13 @@ public class State {
this.id = idCnt++;
}
Map<MatchStrategy, List<State>> next = new HashMap<>();
Map<String, List<State>> next = new HashMap<>();
public void addNext(MatchStrategy path, State state) {
List<State> list = next.get(path);
public void addNext(String edge, State state) {
List<State> list = next.get(edge);
if (list == null) {
list = new ArrayList<>();
next.put(path, list);
next.put(edge, list);
}
list.add(state);
}
......
package xyz.xindoo.re.nfa;
import xyz.xindoo.re.Constant;
import xyz.xindoo.re.State;
import xyz.xindoo.re.nfa.strategy.EpsilonMatchStrategy;
import xyz.xindoo.re.nfa.strategy.MatchStrategy;
public class NFAGraph {
public State start;
......@@ -16,19 +15,17 @@ public class NFAGraph {
public void addParallelGraph(NFAGraph NFAGraph) {
State newStart = new State();
State newEnd = new State();
MatchStrategy path = new EpsilonMatchStrategy();
newStart.addNext(path, this.start);
newStart.addNext(path, NFAGraph.start);
this.end.addNext(path, newEnd);
NFAGraph.end.addNext(path, newEnd);
newStart.addNext(Constant.EPSILON, this.start);
newStart.addNext(Constant.EPSILON, NFAGraph.start);
this.end.addNext(Constant.EPSILON, newEnd);
NFAGraph.end.addNext(Constant.EPSILON, newEnd);
this.start = newStart;
this.end = newEnd;
}
//
public void addSeriesGraph(NFAGraph NFAGraph) {
MatchStrategy path = new EpsilonMatchStrategy();
this.end.addNext(path, NFAGraph.start);
this.end.addNext(Constant.EPSILON, NFAGraph.start);
this.end = NFAGraph.end;
}
......@@ -40,18 +37,16 @@ public class NFAGraph {
// ? 重复0次哦
public void addSToE() {
MatchStrategy path = new EpsilonMatchStrategy();
start.addNext(path, end);
start.addNext(Constant.EPSILON, end);
}
// + 重复1-n次
public void repeatPlus() {
State newStart = new State();
State newEnd = new State();
MatchStrategy path = new EpsilonMatchStrategy();
newStart.addNext(path, this.start);
end.addNext(path, newEnd);
end.addNext(path, start);
newStart.addNext(Constant.EPSILON, this.start);
end.addNext(Constant.EPSILON, newEnd);
end.addNext(Constant.EPSILON, start);
this.start = newStart;
this.end = newEnd;
}
......
package xyz.xindoo.re.nfa.strategy;
public class CharMatchStrategy extends MatchStrategy{
private char cur;
public CharMatchStrategy(char c) {
this.cur = c;
}
private CharMatchStrategy() {
}
@Override
public boolean isMatch(char c) {
return cur == c;
public boolean isMatch(char c, String edge) {
return edge.charAt(0) == c;
}
}
package xyz.xindoo.re.nfa.strategy;
public class CharSetMatchStrategy extends MatchStrategy{
private String charSet = "";
public CharSetMatchStrategy(String charSet, boolean isReverse) {
this.charSet = charSet;
this.isReverse = isReverse;
}
@Override
public boolean isMatch(char c) {
public boolean isMatch(char c, String charSet) {
boolean res = false;
for (int i = 0; i < charSet.length(); i++) {
if (charSet.charAt(0) == '^') {
continue;
}
if ('-' == charSet.charAt(i)) {
return c >= charSet.charAt(i-1) && c <= charSet.charAt(i+1);
}
......@@ -21,7 +16,7 @@ public class CharSetMatchStrategy extends MatchStrategy{
break;
}
}
if (isReverse) {
if (charSet.charAt(0) == '^') {
return !res;
}
return res;
......
......@@ -8,7 +8,7 @@ public class DigitalMatchStrategy extends MatchStrategy{
}
@Override
public boolean isMatch(char c) {
public boolean isMatch(char c, String edge) {
boolean res = c >= '0' && c <= '9';
if (isReverse) {
return !res;
......
......@@ -2,7 +2,7 @@ package xyz.xindoo.re.nfa.strategy;
public class DotMatchStrategy extends MatchStrategy{
@Override
public boolean isMatch(char c) {
public boolean isMatch(char c, String edge) {
return c != '\n' && c != '\r';
}
}
......@@ -2,7 +2,7 @@ package xyz.xindoo.re.nfa.strategy;
public class EpsilonMatchStrategy extends MatchStrategy{
@Override
public boolean isMatch(char c) {
public boolean isMatch(char c, String edge) {
return true;
}
}
......@@ -2,17 +2,7 @@ package xyz.xindoo.re.nfa.strategy;
public class MatchStrategy {
protected boolean isReverse = false;
protected String metaData = "";
public void setReverse(boolean reverse) {
isReverse = reverse;
}
public boolean isMatch(char c){
public boolean isMatch(char c, String edge){
return false;
}
public boolean equals(MatchStrategy other) {
return this.metaData.equals(other.metaData);
}
}
package xyz.xindoo.re.nfa.strategy;
import xyz.xindoo.re.Constant;
import java.util.HashMap;
import java.util.Map;
public class MatchStrategyManager {
private static Map<String, MatchStrategy> matchStrategyMap;
static {
matchStrategyMap = new HashMap<>();
matchStrategyMap.put("\\d", new DigitalMatchStrategy(false));
matchStrategyMap.put("\\D", new DigitalMatchStrategy(true));
matchStrategyMap.put("\\w", new WMatchStrategy(false));
matchStrategyMap.put("\\W", new WMatchStrategy(true));
matchStrategyMap.put("\\s", new SpaceMatchStrategy(false));
matchStrategyMap.put("\\S", new SpaceMatchStrategy(true));
matchStrategyMap.put(".", new DotMatchStrategy());
matchStrategyMap.put(Constant.EPSILON, new EpsilonMatchStrategy());
matchStrategyMap.put(Constant.CHAR, new CharMatchStrategy());
matchStrategyMap.put(Constant.CHARSET, new CharSetMatchStrategy());
}
public static MatchStrategy getStrategy(String key) {
// 特殊字符的匹配
if (matchStrategyMap.containsKey(key)) {
return matchStrategyMap.get(key);
}
// 单字符和字符集的匹配
if (key.length() == 0) {
return matchStrategyMap.get(Constant.CHAR);
} else {
return matchStrategyMap.get(Constant.CHARSET);
}
}
}
......@@ -8,8 +8,8 @@ public class SpaceMatchStrategy extends MatchStrategy{
}
@Override
public boolean isMatch(char c) {
boolean res = c == '\f' || c == '\n' || c == '\r' || c == '\t';
public boolean isMatch(char c, String edge) {
boolean res = (c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == ' ');
if (isReverse) {
return !res;
}
......
......@@ -10,7 +10,7 @@ public class WMatchStrategy extends MatchStrategy{
}
@Override
public boolean isMatch(char c) {
public boolean isMatch(char c, String edge) {
boolean res = c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '0' && c <= '9';
if (isReverse) {
return !res;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册