Соответствие шаблону CLI с использованием Java - PullRequest
1 голос
/ 29 октября 2019

Постановка проблемы

Я работаю над вариантом использования, где у меня есть набор команд, поддерживаемых на устройстве, и фактические команды, которые я хочу выполнить.

Поддерживаемые команды (образец)

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>

Фактические команды (образец)

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

<> являются заполнителями для значений, которыеКоманды могут принимать, а другие являются ключевыми словами. Кроме того, все заполнители будут одинаковыми для данного объекта, например, будет общим заполнителем во всех командах, которые принимают адреса DHCP.

Ожидаемый вывод

Iнужно сопоставить «фактические команды» с «поддерживаемыми командами», а затем сгруппировать их на основе значений в заполнителях в том же порядке, что-то вроде этого.

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

Я пытаюсь добиться этого с помощью Regexсоответствие, но хочу знать, есть ли лучший способ сделать это. Кроме того, поддерживаемые команды и фактические команды могут быть огромными, поэтому требуется эффективный по времени подход.

1 Ответ

0 голосов
/ 29 октября 2019

Я предполагаю, что, возможно, регулярное выражение не будет лучшей идеей здесь, или вы по крайней мере будете использовать комбинированный метод кодирования регулярных выражений для решения проблемы.

Следующее примерное выражение показывает, что «своего рода», как может быть спроектировано регулярное выражение или как вы можете подойти к решению проблемы с этим, если хотите.

^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*$)

, который можно упростить до,

^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*)$

Демо

Это не сложно, просто многословно написать такое выражение,

Тест

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


    }
}

Выход

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

jex.im визуализирует регулярные выражения:

enter image description here


Если вы хотите упростить / изменить / изучить выражение, это объяснено на верхней правой панели regex101.com . Если хотите, вы также можете посмотреть в этой ссылке , как она будет сопоставляться с некоторыми примерами входных данных.


Вероятно, лучшим подходом может быть разделение ваших шаблонов и, соответственно,ваши образцы, а затем написать несколько эффективных методов с желаемой структурой данных, а затем передать ваши образцы с помощью этих методов.

...