0

I'm stuck at this question and hope any one out there can help me.

I have a config file that contains following lines:

config system interface
edit "internal1"
    set vdom "root"
    set ip 192.168.1.1 255.255.255.0
    set allowaccess ping https ssh http fgfm capwap
    set type physical
    set snmp-index 1
next
edit "internal2"
    set vdom "root"
    set ip 192.168.20.2 255.255.255.0
    set allowaccess ping https ssh http fgfm capwap
    set type physical
    set snmp-index 2
    Set secondary-IP enable
      config secondaryip
        edit 1
          set ip 192.168.21.2 255.255.255.0
        next
        edit 2
          set ip 192.168.22.2 255.255.255.0
        next
      end
next
edit "internal3"
    set vdom "root"
    set ip 192.168.30.3 255.255.255.0
    set allowaccess ping https ssh http fgfm capwap
    set type physical
    set snmp-index 3
    Set secondary-IP enable
      config secondaryip
        edit 1
          set ip 192.168.31.3 255.255.255.0
        next
      end
next
end
....

And want to Match for interface's Name, vdom, vlanid, ip and secondary-ip(s) with following regex:

preg_match_all("/edit .+(\s+config secondaryip\r?\n(\s+edit \d+\r?\n.+\s+next\r?\n){1,}\s+end\r?\n)?.+next\r?\n/s", $configFile, $matched_interfaces);

with the first .+ is everything matched and not the others!

Thx for any suggestions

1
  • Make it less greedy. That being said, this file structure does not lend itself to extract-all-at-once. With possibly arbitrary ordering and nesting, some tokenization and state machine would be advisable. Commented Oct 5, 2017 at 20:27

1 Answer 1

0

I love regex

$regex = '/(?<=\vedit ")(\w+)|(?<=vdom ")(\w+)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+set)|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+next)/';
print_r(preg_match_all($regex, $configFile, $matched_interfaces));

Output is

Array
(
[0] => Array
(
[0] => internal1
[1] => root
[2] => 192.168.1.1 255.255.255.0
[3] => internal2
[4] => root
[5] => 192.168.20.2 255.255.255.0
[6] => 192.168.21.2 255.255.255.0
[7] => 192.168.22.2 255.255.255.0
[8] => internal3
[9] => root
[10] => 192.168.30.3 255.255.255.0
[11] => 192.168.31.3 255.255.255.0
)

[1] => Array
(
[0] => internal1
[1] => 
[2] => 
[3] => internal2
[4] => 
[5] => 
[6] => 
[7] => 
[8] => internal3
[9] => 
[10] => 
[11] => 
)

[2] => Array
(
[0] => 
[1] => root
[2] => 
[3] => 
[4] => root
[5] => 
[6] => 
[7] => 
[8] => 
[9] => root
[10] => 
[11] => 
)

[3] => Array
(
[0] => 
[1] => 
[2] => 192.168.1.1 255.255.255.0
[3] => 
[4] => 
[5] => 192.168.20.2 255.255.255.0
[6] => 
[7] => 
[8] => 
[9] => 
[10] => 192.168.30.3 255.255.255.0
[11] => 
)

[4] => Array
(
[0] => 
[1] => 
[2] => 
[3] => 
[4] => 
[5] => 
[6] => 192.168.21.2 255.255.255.0
[7] => 192.168.22.2 255.255.255.0
[8] => 
[9] => 
[10] => 
[11] => 192.168.31.3 255.255.255.0
)

)

Edit to answer follow up

(?<=\vedit ") This is a positive look behind construct, and has to be in parenthesis. This bit ?<= specifies its a positive look behind \v matches vertical whitespace and edit " literally matches edit ". This is followed by (\w+) which means match word characters as many times as you can, putting it in parenthesis creates a capture group so you can reference the match later. The positive look behind means that the (\w+) pattern will only match if the look behind sequence immediately before it also matches

You can add group names to your capture groups to have them returned as a named array

$regex = '/(?<=edit ")(?<name>\w+)\K|(?<=vdom ")(?<vdom>\w+)|(?<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+set)|(?<secondary>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?=\s+next)\K/';
Sign up to request clarification or add additional context in comments.

1 Comment

Many thx miknik!! Could you give me a short explanation of "<?<=\v" and how can I make the match array associative with the corresponding key?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.