Having difficulty getting multi-line Powershell regex to work - no matches

13,806

Solution 1

Try this for your first line instead:

(?s)Subnet = (\d+\.\d+\.\d+\.\d+)\.\W*

You'll also want to look at each line separately:

$output | % { $_ -match $dhcp_regex }

# Append | Out-Null if you don't want each line printed on your screen.

$matches[1]

Edit: here is a more complete example.

$dhcp_regex = 'Subnet = (\d+\.\d+\.\d+\.\d+)'
$dhcp_regex2 = 'in use = (\d+)'
$output | ? { $_ -match $dhcp_regex -or $_ -match $dhcp_regex2} | % { $Matches[1] }

Edit: here is a multiline example.

$dhcp_regex = '(?m)Subnet = (\d+\.\d+\.\d+\.\d+)\.\r\n.*in use = (\d+)'
$output | Out-String | % { $_ -match $dhcp_regex }
$matches

hat tip: http://www.vistax64.com/powershell/80160-powershell-regex-help.html

Edit: Looks like (?m) is not actually necessary. Out-String is the secret sauce.

Solution 2

Changed the regex you provided to add the extra data element.

$dhcp_regex='(?m)Subnet = (\d+\.\d+\.\d+\.\d+)\.\r\n.*in use = (\d+)\.\r\n.* free Addresses = (\d+)\.'

That works fine now - much appreciated! I may spend some time when I'm bored (hehe) to discover in what nuanced way what we were doing before was failing.

Share:
13,806

Related videos on Youtube

Kevin
Author by

Kevin

Updated on September 18, 2022

Comments

  • Kevin
    Kevin over 1 year

    I referred to several examples I was able to search, which seemed highly pertinent, but am still unable to get this to work.

    My input looks like this, from a dhcp server stats command, and I've confirmed that $output is getting defined properly with lines that look like:

    MIBCounts:
            Discovers = 63911.
            Offers = 3903.
            Delayed Offers = 0.
            Requests = 29199.
            Acks = 273080.
            Naks = 71.
            Declines = 0.
            Releases = 395.
            ServerStartTime = Tuesday, March 27, 2012 7:38:53 PM
            Scopes = 34.
            Scopes with Delay configured= 0.
            Subnet = 10.31.0.0.
                    No. of Addresses in use = 203.
                    No. of free Addresses = 40774.
                    No. of pending offers = 0.
            Subnet = 10.32.3.0.
                    No. of Addresses in use = 0.
                    No. of free Addresses = 0.
                    No. of pending offers = 0.
            Subnet = 10.32.100.0.
                    No. of Addresses in use = 48.
                    No. of free Addresses = 145.
                    No. of pending offers = 0.
            Subnet = 10.32.101.0.
                    No. of Addresses in use = 34.
                    No. of free Addresses = 159.
                    No. of pending offers = 0.
    

    So what I tried was this, but got no matches:

    $output=$(netsh -r myserver dhcp server show mibinfo)
    
    $dhcp_regex=@"
    (?s)Subnet = (\d\.\d\.\d\.\d)\.\W+
    .*No\. of Addresses in use = (\d+)\.\W+
    .*No\. of free Addresses = (\d+)\.\W+
    "@
    
    $dhcp_record= {
        @{
            subnet=$matches[0]
            inuse=$matches[1]
            free=$matches[2]
        }}
    
    
    $output -match $dhcp_regex
    
    $matches
    

    Assistance appreciated.

  • Kevin
    Kevin about 12 years
    Ok, tried the first, nothing. Tried the second, and yes, it works, but it doesn't really represent the "inline, need to match the whole pattern" objective. If it happened to get 2 lines of "in use" in a row, I'd still get output. In this particular case, our input format we're parsing is extremely well known, and we can rely on the pattern of alternation being followed. For me however, I treat these situations as instructive and want rigorous solutions that will stand up when I know my data input is not as clean. I'd like to make the original form work as it's more exact.
  • northben
    northben about 12 years
    Fair enough. That's how I approach these things too. I will amend my comment with another approach.
  • jscott
    jscott about 12 years
    Was this to be a comment on @northben's answer? If so, please move.. If this was intended to be the correct answer, don't forget to mark it as "accepted".