Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
In theory that's an ideal task for regexp assertions in Perl code. Unfortunatly such assertions are rather convoluted to do in current day perl, though it does work.

Let's first try the simplified task to find if a number matches an integer that is between 0 and 255 (incl). The lower border is easy, all you need to do is forbid a minus sign. So all you have to do is test if a matched number is below 256.

Here's a demo to see if an integer is below 256:

($\, $,) = ("\n", "\t"); print $_, /\b(\d+)\b(?(?{$1 >= 256})(?!))/ ? 'Y' : 'N' for 0 .. 1000;
This prints, summarized:
0	Y
1	Y
2	Y
...
254	Y
255	Y
256	N
257	N
...
1000	N

So how does it work? First of all, we try to match an integer, using

/\b(\d+)\b/
The "\b" is desired when using assertions, in order to prevent substrings to match instead of the whole. Otherwise, if you have a string "1234", the substring "123" is less than 256 and would match. We can't use that.

The next part is a pattern of the form

(?(condition)yes-pattern)
which will try to match the "yes-pattern" only if the condition (a regex pattern itself) is met. The condition takes the form here:
(?{ code })
which executes code, and which normally always succeeds; but which in this special usage case serves as a switch to conditionally test the following yes-pattern.

And that yes-pattern takes the form

(?!)
which actually is a plain negative lookahead, which essentially says "whatever it is that follows now, it is wrong." So, essentially, it always fails.

The net effect is the condition has to be the wrong way around: it must return true when we want the math to fail. In this example, we have code to test if what is matched is 256 or above, and if so, fail by trying (and failing) to match /(?!)/.

As a whole, we can try matching an 4-dotted quad IP address using the regexp:

/^(\d+)(?(?{$1 >= 256})(?!))\.(\d+)(?(?{$2 >= 256})(?!))\.(\d+)(?(?{$3 + >= 256})(?!))\.(\d+)(?(?{$4 >= 256})(?!))$/
but we might as well combine the separate conditions into one:
/^(\d+)\.(\d+)\.(\d+)\.(\d+)$(?(?{$1 >= 256 || $2 > 256 || $3 >= 256 | +|$4 >= 256})(?!))/

Do note that I can leave off the \b anchors, because I have enough other sideconditions: andchors /^/ and /$/, as well as a need to match /\./ next.


In reply to Re: Regular Expression to Match IP Address by bart
in thread Regular Expression to Match IP Address by sashac88

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2024-04-25 05:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found