正则表达式:如何匹配不跟在 #&&,但必须跟在 &&后面的字符串



我正在尝试匹配字符串&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

  1. " true"如果有匹配或" false",否则
  2. 字符串中匹配开始的位置,或者-1如果没有匹配项
  3. 匹配的字符串。

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

}

相关内容

  • 没有找到相关文章

最新更新