header1   header
header
header Register : : Login header
header
connector   connector
menuleft menuright
submenu   submenu
left
Regular Expressions : Negative Lookback
Last Post 19 May 2011 12:27 PM by Matt. 18 Replies.
Printer Friendly
  •  
  •  
  •  
  •  
  •  
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages Resolved
LMizuhashiUser is Offline
New Member
New Member
Posts:24
Avatar

--
09 May 2011 09:09 AM
    I'm trying to write a function that takes a single IP Address from the pipeline as its only parameter. Here's how I've got the parameter defined:

        Param (          [parameter(Mandatory=$true,                     ValueFromPipeline=$true)]          [ValidateNotNullOrEmpty()]          [ValidatePattern("[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")]          [String]$IPAddress      )


    I assume that any IP Address starting with the number 0 is invalid. I'm trying to use a negative lookback to tell the script to ignore any IP Address that starts with a zero. Perhaps something like this?

        Param (          [parameter(Mandatory=$true,                     ValueFromPipeline=$true)]          [ValidateNotNullOrEmpty()]          [ValidatePattern("(?[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")]
             [String]$IPAddress
         )


    Doesn't work for me; it still lets garbage like '0123.456.789.012' through. =(

    (It also lets '100000000000000004600.6.110.219' through too, for that matter. I guess {1,3} isn't working as well.)

    Any solutions?
    LMizuhashiUser is Offline
    New Member
    New Member
    Posts:24
    Avatar

    --
    09 May 2011 09:15 AM
    Jesus Christ, this editor sucks. I'm done fixing the above post. Off to lunch. Grrr......
    JonathanUser is Offline
    Basic Member
    Basic Member
    Posts:109
    Avatar

    --
    09 May 2011 09:28 AM
    How about this?

    (2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)

    This one has worked for me when testing for IP Addresses.

    Jonathan Tyler
    http://powershellreflections.wordpress.com
    Follow Me On Twitter
    LMizuhashiUser is Offline
    New Member
    New Member
    Posts:24
    Avatar

    --
    09 May 2011 09:34 AM
    Thanks for the input, guys.

    This IP slips through the validation: '012.6.110.219'
    0ptikGhostUser is Offline
    Basic Member
    Basic Member
    Posts:367
    Avatar

    --
    09 May 2011 09:36 AM

    The [ValidatePattern()] attribute uses the -match operator to validate the parameter. The -match operator returns true if any part of the input string matches the regular expression. You'll want to use ^ and $ in the regular expression to indicate that you want the entire string to be matched. Using Jonathan's regular expression as an example:

    [ValidatePattern('^(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)$')]
    LMizuhashiUser is Offline
    New Member
    New Member
    Posts:24
    Avatar

    --
    09 May 2011 09:49 AM
    How's this for verbose? (And also not functional... )
     (1|1[0-9]|1[0-9][0-9]|2|2[0-9]|2[0-5][0-5]|3|3[0-9]|4|4[0-9]|5|5[0-9]|6|6[0-9]|7|7[0-9]|8|8[0-9]|9|9[0-9])\.(1|1[0-9]|1[0-9][0-9]|2|2[0-9]|2[0-5][0-5]|3|3[0-9]|4|4[0-9]|5|5[0-9]|6|6[0-9]|7|7[0-9]|8|8[0-9]|9|9[0-9])\.(1|1[0-9]|1[0-9][0-9]|2|2[0-9]|2[0-5][0-5]|3|3[0-9]|4|4[0-9]|5|5[0-9]|6|6[0-9]|7|7[0-9]|8|8[0-9]|9|9[0-9])\.(1|1[0-9]|1[0-9][0-9]|2|2[0-9]|2[0-5][0-5]|3|3[0-9]|4|4[0-9]|5|5[0-9]|6|6[0-9]|7|7[0-9]|8|8[0-9]|9|9[0-9])


    LOL
    LMizuhashiUser is Offline
    New Member
    New Member
    Posts:24
    Avatar

    --
    09 May 2011 10:39 AM
    Hmmm.... none of the above works yet.

    This, though oh so ugly, will pass only numbers 1 through 255:

    "^[1][0-9]{0,2}$|^[2][0-9]{0,1}$|^[2][0-4][0-9]$|^[2][5][0-5]$|^[3]$|^[3][0-9]$|^[4]$|^[4][0-9]$|^[5]$|^[5][0-9]$|^[6]$|^[6][0-9]$|^[7]$|^[7][0-9]$|^[8]$|^[8][0-9]$|^[9]$|^[9][0-9]$"

    I wonder how we make it more graceful--and examine the pattern of an IP Address?
    LMizuhashiUser is Offline
    New Member
    New Member
    Posts:24
    Avatar

    --
    09 May 2011 10:43 AM
    Here we go. This is a little better...

    "^[1][0-9]{0,2}$|^[2][0-9]{0,1}$|^[2][0-4][0-9]$|^[2][5][0-5]$|^[3][0-9]{0,1}$|^[4][0-9]{0,1}$|^[5][0-9]{0,1}$|^[6][0-9]{0,1}$|^[7][0-9]{0,1}$|^[8][0-9]{0,1}$|^[9][0-9]{0,1}$"
    cameronoveUser is Offline
    Basic Member
    Basic Member
    Posts:352
    Avatar

    --
    09 May 2011 01:47 PM
    I built a function for my IP checking:

    function Check-ValidIP([string]$IP){
        $ValidIP = $true
    $ValidIP
    = ($IP-match"^[1-9]\d{0,2}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") if(-not $ValidIP){return $false} $myip = $IP -split"\."
    $ValidIP = ([int]$myip[0] -gt 0 -and [int]$myip[0] -le 255) if(-not $ValidIP){return $false} for($i=1;$i-le3;$i++){ $ValidIP = ([int]$myip[$i] -ge 0 -and [int]$myip[$i] -le 255) if(-not $ValidIP){return $false} } return $ValidIP }


    It will return true or false depending on whether the IP is valid. I know it's not a regex pattern, but regex is not meant to check numeric values, so doing a check for between 0-255 is ugly, confusing, and unreadable especially when you have to do it for 4 octets.
    cameronoveUser is Offline
    Basic Member
    Basic Member
    Posts:352
    Avatar

    --
    09 May 2011 02:08 PM
    Resubmitting function with proper verb and some comments.
    function Test-ValidIP([string]$IP){
        $ValidIP = $true #Start off on the right foot

    <#
    Test format and leading zero (technically not necessary to test for leading zero as this function strips the leading zero when converting to [int]#>
    $ValidIP
    = ($IP -match "^[1-9]\d{0,2}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") if(-not $ValidIP){return $false}

     
    $myip = $IP -split "\." #Each octet is element of an array

    $ValidIP
    = ([int]$myip[0] -gt 0 -and [int]$myip[0] -le 255) #First octet is between 1-255
    if
    (-not $ValidIP){return $false}
    for($i = 1;$i -le 3;$i++){ $ValidIP = ([int]$myip[$i] -ge 0 -and [int]$myip[$i] -le 255) #Remain octets between 0-255
    if(-not $ValidIP){return $false} }
    return
    $ValidIP #$ValidIP will always be true at this point.
    }


    MattUser is Offline
    New Member
    New Member
    Posts:31
    Avatar

    --
    10 May 2011 03:27 AM
    • Accepted Answer
    You could always use the .Net IP Address type as well

    functionTest-ValidIP([string]$IP){
        try { [IPAddress] $IPAddress=$IP } catch { return$false}
        return$true
    }
    
    Web: http://amonkeysden.tumblr.com
    Twitter: @aMonkeysDen
    cameronoveUser is Offline
    Basic Member
    Basic Member
    Posts:352
    Avatar

    --
    10 May 2011 05:41 AM
    I like that Matt.
    JonathanUser is Offline
    Basic Member
    Basic Member
    Posts:109
    Avatar

    --
    10 May 2011 06:18 AM
    I had seen this option earlier in the week, but had slipped my mind. Awesome idea!
    Jonathan Tyler
    http://powershellreflections.wordpress.com
    Follow Me On Twitter
    MattUser is Offline
    New Member
    New Member
    Posts:31
    Avatar

    --
    10 May 2011 12:34 PM
    :)
    Web: http://amonkeysden.tumblr.com
    Twitter: @aMonkeysDen
    LMizuhashiUser is Offline
    New Member
    New Member
    Posts:24
    Avatar

    --
    10 May 2011 12:45 PM
    Building a regression equation to verify IP Addresses: four hours
    Rewriting all of your scripts to accept that you're probably going to have to pass IP's as PowerShell objects with one property for each octet: four hours
    Finding out afterwards that there's a .NET type for doing the same thing in four lines or less: Priceless

    Somethings in life require a lot of code; for everything else, there's .NET
    Shay LevyUser is Offline
    PowerShell MVP, Admin
    Veteran Member
    Veteran Member
    Posts:1362
    Avatar

    --
    10 May 2011 11:17 PM
    Here's another option using the -AS operator:

    function Test-IPAddress([string]$IP){ [bool]($IP -as [IPAddress]) }

    Shay Levy
    Windows PowerShell MVP
    http://PowerShay.com
    PowerShell Community Toolbar
    Twitter: @ShayLevy
    MattUser is Offline
    New Member
    New Member
    Posts:31
    Avatar

    --
    11 May 2011 12:21 AM
    One line! Nice. Is it testing it or converting it? I'm guessing, from the grammar, it's converting it?


    Web: http://amonkeysden.tumblr.com
    Twitter: @aMonkeysDen
    Shay LevyUser is Offline
    PowerShell MVP, Admin
    Veteran Member
    Veteran Member
    Posts:1362
    Avatar

    --
    11 May 2011 12:32 AM
    The -as parameter tries to convert it, if it succeed you get an ipaddress object back, otherwise you get null.

    Shay Levy
    Windows PowerShell MVP
    http://PowerShay.com
    PowerShell Community Toolbar
    Twitter: @ShayLevy
    MattUser is Offline
    New Member
    New Member
    Posts:31
    Avatar

    --
    19 May 2011 12:27 PM
    Thanks Shay, I used this in anger this week - always good to learn something useful. :)
    Web: http://amonkeysden.tumblr.com
    Twitter: @aMonkeysDen
    You are not authorized to post a reply.


    Active Forums 4.3
    right
    footer   footer
    footer Sponsored by Quest Software • SAPIEN Technologies • Compellent • Microsoft Windows Server 2008 R2 footer
    footer   footer