我正在尝试匹配字符串&abD&eG
来自abCD#&&abCD&abD&eG
一般规则是:匹配由必须遵循&
但不能遵循#&&
的alpha组成的字符串。但是,一旦字符串以单个&
开头,#&&
仍被视为比赛的一部分。连续&
的s将算作匹配。
因此,一些简化的样品字符串和匹配为:
#&&abc&abc
应该匹配:&abc
&abc&abc
应该匹配:&abc&abc
#&&abc&abc#&&abc
应该匹配:&abc#&&abc
#&&abc#&&abc
应该匹配:没有匹配
#&&abc
应该匹配:没有匹配
abc#&&
应该匹配:没有匹配
abc
应该匹配:没有匹配
&&abc&abc
应该匹配:&&abc&abc
&&abc#&&
应该匹配:&&abc#&&
#&&&&abc
应该匹配:&&abc
&&abc&abc&&&&
应该匹配:&&abc&abc&&&&
&&&
应该匹配:&&&
abc&abc
应该匹配:&abc
i当前有正则 (?<!#&&)(&p{Alnum}+)+
,但它在&
之后检测到序列,无论其后面是否伴随着#&amp;。我应该如何修改它,以使其与我的一般规则相应匹配?
我尝试为此构建一条正则义务,但是由于&
是两者的一部分,因此排除匹配项的标记,也包括在比赛中包含的角色,它变得非常复杂,对于可以通过简单的FDA检测到的东西。
如果您有任何用途,我将在这里留下算法。它是在Java中实现的,但是将其移植其他语言不应该是问题。
match
方法返回具有三个值的ArrayList
:
- " true"如果有匹配或" false",否则
- 字符串中匹配开始的位置,或者-1如果没有匹配项
-
匹配的字符串。
public class SO47732442 { private int [] [] states = { {1,4,0}, {3,2,3}, {3,0,3}, {3,3,3}, {3,3,3} }; private int state = 0; private int getCol(char c){ int rtn = 4; switch(c){ case '#': rtn = 0; break; case '&': rtn = 1; break; default: rtn = 2; } return rtn; } public ArrayList<String> match(String text){ state = 0; ArrayList<String> rtn = new ArrayList<>(); StringBuilder sb = new StringBuilder(); int start = -1; boolean match = false; for(int i=0; i<text.length();i++){ int col = getCol(text.charAt(i)); state = states[state][col]; if(state == 3){ if(!match){ sb.append("&"); start = i; match = true; } sb.append(text.charAt(i)); } } rtn.add(match? "true" : "false"); rtn.add(""+start); rtn.add(sb.toString()); return rtn; } /* This is just to test the matches */ public static void main(String[] args){ SO47732442 app = new SO47732442(); ArrayList<String> tests = new ArrayList<>(); tests.add("#&&abc&abc"); tests.add("&abc&abc"); tests.add("#&&abc&abc#&&abc"); tests.add("#&&abc#&&abc"); tests.add("#&&abc"); tests.add("abc#&&"); tests.add("abc"); tests.add("&&abc&abc "); tests.add("&&abc#&&"); tests.add("#&&&&abc"); tests.add("&&abc&abc&&&&"); tests.add("&&&"); tests.add("abc&abc"); tests.add("abcabc&"); for(String test : tests){ System.out.println("Text: " + test); ArrayList<String> result = app.match(test); for(String res : result){ System.out.println(res); } System.out.println(""); } } }
无法使正则命令工作,但是这里有一个通过所有测试用例的函数(可能可以稍微清理一点):
public static String getMatch(String string) {
int startIndex = 0;
while (string.indexOf("&", startIndex) > string.indexOf("#&&", startIndex))
{
if (string.indexOf("&", startIndex) < 0) return "";
if (string.indexOf("#&&", startIndex) < 0) return string.substring(string.indexOf("&", startIndex));
startIndex = string.indexOf("#&&", startIndex) + 3;
}
return (string.indexOf("&", startIndex) < 0) ? "" : string.substring(string.indexOf("&", startIndex));
}