简体   繁体   English

使用 Java 进行 CLI 模式匹配

[英]CLI pattern Matching using Java

Problem Statement问题陈述

I'm working on a use case where I have a set of commands supported on a device and actual commands that I want to execute.我正在研究一个用例,其中我有一组设备支持的命令和我想要执行的实际命令。

Commands Supported (Sample)支持的命令(示例)

config dhcp ip <dhcp-ipaddress> port <dhcp-port-number>
config dhcp ip <dhcp-ipaddress> timeout <time-out-value>
config dhcp ipv4 <dhcp-ipaddress>
config dns ip <dns-ipaddress> port <dns-port-number>
config dns ip <dns-ipaddress> timeout <time-out-value>
config router bgp <bgp-number>
config interface id <interface-id> 
config interface name <interface-name> id <interface-id>

Actual Commands (Sample)实际命令(示例)

config dhcp ip 1.1.1.1 port 8080
config dhcp ip 1.1.1.2 timeout 120
config dhcp ip 1.1.1.1 timeout 120
config dhcp ip 1.1.1.2 port 8080
config dhcp ipv4 1.1.1.3
config interface id 12 
config interface name abc id 12
config interface id 13 
config interface name xyz id 13

<> are the placeholders for the values the commands can take and others are keywords. <> 是命令可以采用的值的占位符,其他是关键字。 Also, all the placeholders will be the same for a given entity, for instance will a common placeholder in all the commands which take DHCP addresses.此外,对于给定实体,所有占位符都是相同的,例如,在所有采用 DHCP 地址的命令中将有一个共同的占位符。

Expected Output预计 Output

I have to match the "actual commands" with the "commands supported" and then group them based on the values in the placeholders in the same order something like this.我必须将“实际命令”与“支持的命令”匹配,然后根据占位符中的值以相同的顺序对它们进行分组,如下所示。

config dhcp ip 1.1.1.1 port 8080
config dhcp ip 1.1.1.1 timeout 120

config dhcp ip 1.1.1.2 timeout 120
config dhcp ip 1.1.1.2 port 8080

config dhcp ipv4 1.1.1.3

config interface id 12 
config interface name abc id 12

config interface id 13 
config interface name xyz id 13

I am trying to achieve this with Regex matching but want to know if there is a better way to do it.我正在尝试通过正则表达式匹配来实现这一点,但想知道是否有更好的方法来做到这一点。 Also, the commands supported and actual commands could be huge, so looking for a time-efficient approach.此外,支持的命令和实际命令可能非常庞大,因此需要寻找一种省时的方法。

I'm guessing that maybe regular expression wouldn't be the best idea here, or you are going to at least have a combined regex-coding method to solve the problem.我猜也许正则表达式在这里不是最好的主意,或者你至少会有一个组合的正则表达式编码方法来解决这个问题。

The following exampled expression is showing that, "kind of", how a regular expression can be designed or how you might approach solving the problem with that, if you wish so.下面的示例表达式显示“种类”,如何设计正则表达式,或者如果您愿意,您可以如何解决这个问题。

^config d(hcp|ns) ip(v4)? (<[^>]*>|(?:\\d+\\.){3}\\d+)( port| timeout|\\s*$)( <[^>]*>\\s*$| \\d+\\s*$|\\s*$)|config (router|interface) (id|bgp|name) (<[^>]*>\\s*$|<[^>]*> id <[^>]*>\\s*$|\\d+\\s*$|[a-z]+ id \\d+\\s*$|\\s*$)

which can be simplified to,可以简化为,

^config (dhcp|dns|router|interface) (?:ip|ipv4|id|bgp|name) (<[^>]*>|(?:\\d+\\.){3}\\d+|[a-z]+ id \\d+|\\d+)( port| timeout| id|\\s*)( <[^>]*>\\s*| \\d+\\s*|\\s*)$

Demo演示

It's not complicated, is just verbose to write an expression like that.这并不复杂,只是写一个这样的表达式很冗长。

Test测试

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex = "^config (dhcp|dns|router|interface) (?:ip|ipv4|id|bgp|name) (<[^>]*>|(?:\\d+\\.){3}\\d+|[a-z]+ id \\d+|\\d+)( port| timeout| id|\\s*)( <[^>]*>\\s*| \\d+\\s*|\\s*)$";
        final String string = "config dhcp ip <dhcp-ipaddress> port <dhcp-port-number>\n"
             + "config dhcp ip <dhcp-ipaddress> timeout <time-out-value>\n"
             + "config dhcp ipv4 <dhcp-ipaddress>\n"
             + "config dns ip <dns-ipaddress> port <dns-port-number>\n"
             + "config dns ip <dns-ipaddress> timeout <time-out-value>\n"
             + "config router bgp <bgp-number>\n"
             + "config interface id <interface-id> \n"
             + "config interface name <interface-name> id <interface-id>\n\n"
             + "config dhcp ip 1.1.1.1 port 8080\n"
             + "config dhcp ip 1.1.1.2 timeout 120\n"
             + "config dhcp ip 1.1.1.1 timeout 120\n"
             + "config dhcp ip 1.1.1.2 port 8080\n"
             + "config dhcp ipv4 1.1.1.3\n"
             + "config interface id 12 \n"
             + "config interface name abc id 12\n"
             + "config interface id 13 \n"
             + "config interface name xyz id 13\n\n"
             + "config dhcp ip 1.1.1.1 port 8080\n"
             + "config dhcp ip 1.1.1.1 timeout 120\n"
             + "config dhcp ip 1.1.1.2 timeout 120\n"
             + "config dhcp ip 1.1.1.2 port 8080\n"
             + "config dhcp ipv4 1.1.1.3\n"
             + "config interface id 12 \n"
             + "config interface name abc id 12\n"
             + "config interface id 13 \n"
             + "config interface name xyz id 13";

        final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(string);

        while (matcher.find()) {
            System.out.println("Full match: " + matcher.group(0));
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Group " + i + ": " + matcher.group(i));
            }
        }


    }
}

Output Output

Full match: config dhcp ip <dhcp-ipaddress> port <dhcp-port-number>
Group 1: dhcp
Group 2: <dhcp-ipaddress>
Group 3:  port
Group 4:  <dhcp-port-number>
Full match: config dhcp ip <dhcp-ipaddress> timeout <time-out-value>
Group 1: dhcp
Group 2: <dhcp-ipaddress>
Group 3:  timeout
Group 4:  <time-out-value>
Full match: config dhcp ipv4 <dhcp-ipaddress>
Group 1: dhcp
Group 2: <dhcp-ipaddress>
Group 3: 
Group 4: 
Full match: config dns ip <dns-ipaddress> port <dns-port-number>
Group 1: dns
Group 2: <dns-ipaddress>
Group 3:  port
Group 4:  <dns-port-number>
Full match: config dns ip <dns-ipaddress> timeout <time-out-value>
Group 1: dns
Group 2: <dns-ipaddress>
Group 3:  timeout
Group 4:  <time-out-value>
Full match: config router bgp <bgp-number>
Group 1: router
Group 2: <bgp-number>
Group 3: 
Group 4: 
Full match: config interface id <interface-id> 
Group 1: interface
Group 2: <interface-id>
Group 3:  
Group 4: 
Full match: config interface name <interface-name> id <interface-id>

Group 1: interface
Group 2: <interface-name>
Group 3:  id
Group 4:  <interface-id>

Full match: config dhcp ip 1.1.1.1 port 8080
Group 1: dhcp
Group 2: 1.1.1.1
Group 3:  port
Group 4:  8080
Full match: config dhcp ip 1.1.1.2 timeout 120
Group 1: dhcp
Group 2: 1.1.1.2
Group 3:  timeout
Group 4:  120
Full match: config dhcp ip 1.1.1.1 timeout 120
Group 1: dhcp
Group 2: 1.1.1.1
Group 3:  timeout
Group 4:  120
Full match: config dhcp ip 1.1.1.2 port 8080
Group 1: dhcp
Group 2: 1.1.1.2
Group 3:  port
Group 4:  8080
Full match: config dhcp ipv4 1.1.1.3
Group 1: dhcp
Group 2: 1.1.1.3
Group 3: 
Group 4: 
Full match: config interface id 12 
Group 1: interface
Group 2: 12
Group 3:  
Group 4: 
Full match: config interface name abc id 12
Group 1: interface
Group 2: abc id 12
Group 3: 
Group 4: 
Full match: config interface id 13 
Group 1: interface
Group 2: 13
Group 3:  
Group 4: 
Full match: config interface name xyz id 13

Group 1: interface
Group 2: xyz id 13
Group 3: 

Group 4: 
Full match: config dhcp ip 1.1.1.1 port 8080
Group 1: dhcp
Group 2: 1.1.1.1
Group 3:  port
Group 4:  8080
Full match: config dhcp ip 1.1.1.1 timeout 120
Group 1: dhcp
Group 2: 1.1.1.1
Group 3:  timeout
Group 4:  120
Full match: config dhcp ip 1.1.1.2 timeout 120
Group 1: dhcp
Group 2: 1.1.1.2
Group 3:  timeout
Group 4:  120
Full match: config dhcp ip 1.1.1.2 port 8080
Group 1: dhcp
Group 2: 1.1.1.2
Group 3:  port
Group 4:  8080
Full match: config dhcp ipv4 1.1.1.3
Group 1: dhcp
Group 2: 1.1.1.3
Group 3: 
Group 4: 
Full match: config interface id 12 
Group 1: interface
Group 2: 12
Group 3:  
Group 4: 
Full match: config interface name abc id 12
Group 1: interface
Group 2: abc id 12
Group 3: 
Group 4: 
Full match: config interface id 13 
Group 1: interface
Group 2: 13
Group 3:  
Group 4: 
Full match: config interface name xyz id 13
Group 1: interface
Group 2: xyz id 13
Group 3: 
Group 4: 

RegEx Circuit正则表达式电路

jex.im visualizes regular expressions: jex.im可视化正则表达式:

在此处输入图像描述


If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com .如果您想简化/修改/探索表达式,它已在regex101.com的右上角面板上进行了解释。 If you'd like, you can also watch in this link , how it would match against some sample inputs.如果您愿意,您还可以在此链接中观看它如何与一些示例输入匹配。


A likely better approach might be to split your patterns and accordingly your samples, and then write few efficient methods with your desired data structure, then feed your samples through those methods.一种可能更好的方法可能是拆分您的模式并相应地拆分您的样本,然后使用您所需的数据结构编写一些有效的方法,然后通过这些方法提供您的样本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM