1
votes

1) My string is below

% set a {
    absdsdgfg
    dsdgsdg
    sdgsdgsd
    asdas192.168.2.1
    asdfsdf
    sdfsdf
    10.10.10.1
}
absdsdgfg
dsdgsdg
sdgsdgsd
asdas192.168.2.1
asdfsdf
sdfsdf
10.10.10.1

2) Regular expression is

% regexp {.*(\d+\.\d+\.\d+\.\d+).*} $a -> ip
1

3) Output

% set ip
0.10.10.1    
%

In the Step Number - 3 I am getting the output as 0.10.10.1 . Why I am missing 1 here? It is a number it should match with \d, but why it is maching with (.*).

2

2 Answers

4
votes

The first .* is eating the 1.

To avoid this from happening, you can use a lazy version of .* that is: .*?

The reason behind is is that the first .* first matches everything until the end of the string and then goes back one character at a time checking for the other characters which are yet to be matched by the regex.

Once it has gone back to the point before the 0 here: 0.10.10.1, the last part of the regex matches (meaning it won't go back more than that) and the regex returns a successful match.

And this is what goes into the captured group, you named ip.

The .*? however will match as little as possible and will get 192.168.2.1. If you want to get 10.10.10.1, use this regex:

regexp {.*?(\d+\.\d+\.\d+\.\d+)\s*$} $a -> ip

Or you can have it shorter:

regexp {.*?(\d+(?:\.\d+){3})\s*$} $a -> ip

And actually, the .*? is not even needed here:

regexp {(\d+(?:\.\d+){3})\s*$} $a -> ip
0
votes

For a string set a { absdsdgfg dsdgsdg sdgsdgsd asdas192.168.2.1 asdfsdf sdfsdf 10.10.10.1 } Use a Regular Expression : % regexp -all {(\d+.\d+.\d+.\d+)} $a ip %puts "$ip" 10.10.10.1