Regex 正则表达式,用于在找到文本而缺少其他文本时进行搜索

Regex 正则表达式,用于在找到文本而缺少其他文本时进行搜索,regex,Regex,我有以下案文: application ONE { protocol tcp; destination-port 50; } application TWO { protocol udp; destination-port 51; inactivity-timeout 800; } application THREE { protocol udp; destination-port 500; } 当协议为udp时,如果非活动超时不同于18

我有以下案文:

application ONE {
    protocol tcp;
    destination-port 50;
}
application TWO {
    protocol udp;
    destination-port 51;
    inactivity-timeout 800;
}
application THREE {
    protocol udp;
    destination-port 500;
}
协议
udp
时,如果
非活动超时
不同于1800(应用程序二)或
协议
udp
且未定义非活动(应用程序三),我需要搜索每个
应用程序。
我用正则表达式解决了第一个问题:

(?s)(?=protocol udp).*(inactivity-timeout (?!1800))
但我还没找到办法得到第二个


有什么建议吗?

你用Java标记了这一点,所以我给你提供了一个Java解决方案,尽管从你的帖子中我不确定这是否是你想要的

我个人会把这个问题分成两部分。首先,提取应用程序,然后检查应用程序是否满足要求。这是我的尝试

public class ApplicationReadOut {

    public static String EXAMLPLE = "application ONE {\r\n"
        +"    protocol tcp;\r\n"
        +"    destination-port 50;\r\n"
        +"}\r\n"
        +"application TWO {\r\n"
        +"    protocol udp;\r\n"
        +"    destination-port 51;\r\n"
        +"    inactivity-timeout 800;\r\n"
        +"}\r\n"
        +"application THREE {\r\n"
        +"    protocol udp;\r\n"
        +"    destination-port 500;\r\n"
        +"}\r\n";

    public boolean checkApplication(String app) {
        String[] lines = app.split("\r\n");
        boolean udp = false;
        boolean timeoutDiffers = true;
        boolean timeoutMentioned = false;
        for (String line : lines) {
            if (line.trim().equals("protocol udp;"))
                udp = true;
            if (line.trim().equals("inactivity-timeout 1800;"))
                timeoutDiffers = false;
            if (line.trim().startsWith("inactivity-timeout "))
                timeoutMentioned = true;
        }
        return udp & (timeoutDiffers | !timeoutMentioned);
    }

    public String[] extractApplications(String text) {
        String[] applications = text.split("}(\r*\n*)*"); 
        // the \r\n thing is to ignore blank lines in between applications
        ArrayList<String> goodApps = new ArrayList<String>(applications.length);
        for (int i = 0; i < applications.length; i++) {
            applications[i] += "}"; // this was removed by split
            if (checkApplication(applications[i]))
                goodApps.add(applications[i]);
        }
        return goodApps.toArray(new String[0]);
    }


    public static void main(String[] args) {
        ApplicationReadOut aro = new ApplicationReadOut();
        System.out.println(Arrays.toString(aro.extractApplications(EXAMLPLE)));
    }

}
公共类应用程序读取{
public static String example=“应用程序一{\r\n”
+“协议tcp;\r\n”
+“目标端口50;\r\n”
+“}\r\n”
+“应用程序二{\r\n”
+“协议udp;\r\n”
+“目标端口51;\r\n”
+“非活动超时800;\r\n”
+“}\r\n”
+“应用程序三{\r\n”
+“协议udp;\r\n”
+“目标端口500;\r\n”
+“}\r\n”;
公共布尔校验应用程序(字符串应用程序){
String[]line=app.split(“\r\n”);
布尔udp=false;
布尔TimeOutDifferences=true;
boolean timeouttheated=false;
用于(字符串行:行){
if(line.trim().equals(“协议udp;”)
udp=真;
if(line.trim()等于(“非活动超时1800;”)
TimeOutDifferences=false;
if(line.trim().startsWith(“非活动超时”))
timeoutattered=true;
}
返回udp&(TimeOutDifferences |!TimeOutDifferentied);
}
公共字符串[]提取应用程序(字符串文本){
String[]applications=text.split(“}(\r*\n*)*”);
//\r\n问题是忽略应用程序之间的空白行
ArrayList goodApps=新的ArrayList(applications.length);
对于(int i=0;i

我希望这是有用的,您可以修改它以满足您的需要:-)

这应该可以完成以下工作:

application\s*([a-z]*)\s*{(?=(?=\s*protocol udp*)(?!inactivity-timeout.*))|(?=(?=\s*protocol udp*)(?!inactivity-timeout\s1800))(?=})
您需要使用
/img
进行多行、不区分大小写和全局搜索


解释和你的例子。

你好,格林索尔,谢谢你的回答。我这边用Java标记它是一个错误,我的意思是Java正则表达式,我不能这样做:-(对此我无能为力,抱歉。但是你能回答我很好:-)嗨,尼尔斯,非常感谢你的回答。我已经测试了一段时间,但我不确定它是否如预期的那样工作。我认为这项工作是由第一个或第二个国家完成的。如果我在应用程序2中将innactivity值更改为1800,则正则表达式仍与之匹配。如果我删除第二个或正则表达式,它仍然与应用程序2和应用程序3匹配。非常感谢你的帮助