Discussion:
Problem with [environment]::NewLine and Regular Expression
(too old to reply)
unknown
2007-11-28 02:41:02 UTC
Permalink
Here is my powershell code:

$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))

##$tabFile = @"
##[Subnet : "172.29.11.0(VLAN19)"]
## Subnet Address = 172.29.11.0
## Subnet Mask = 255.255.255.0
## Lease Time = 259200
## Config Options = 00 00 00 00 03 04 AC 1D 0B 01
## Zone Reference = bdokendalls_com_au.BDOK
## Domain Name = bdokendalls.com.au
## Subnet Type = 1
##
##[Subnet Address Range : "Subnet Server.VLAN19.BDOK"]
## Start Address = 172.29.11.0
## End Address = 172.29.11.0
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 99
##
##[Subnet Address Range : "LAN.VLAN19.BDOK"]
## Start Address = 172.29.11.50
## End Address = 172.29.11.250
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 3
## DNS Update Option = 2
##"@


$RegexOptions = [System.Text.RegularExpressions.RegexOptions]
$options = ($RegexOptions::Multiline -bor $RegexOptions::IgnoreCase)

$regex = @"
^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\n\t(?<lines>.+?))*$

"@


$reg = new-object System.Text.RegularExpressions.Regex($regex, $options)


$matches = $reg.Matches($tabFile)
$matches.Count

$matches | Foreach-Object {
$_.Groups["name"].Value
$_.Groups["desc"].Value
$_.Groups["lines"].Captures | foreach-Object {
$_.Value
}

}

I've tested this regular expression in a program called the regulator and it
works perfectly. Unfortunately when running it in powershell it does not
match anything. If I remove the $ it does match some of what i want but not
all. Is this a bug?
--
**********************
Jacob
Jeff
2007-11-28 05:11:20 UTC
Permalink
Post by unknown
$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))
##[Subnet : "172.29.11.0(VLAN19)"]
## Subnet Address = 172.29.11.0
## Subnet Mask = 255.255.255.0
## Lease Time = 259200
## Config Options = 00 00 00 00 03 04 AC 1D 0B 01
## Zone Reference = bdokendalls_com_au.BDOK
## Domain Name = bdokendalls.com.au
## Subnet Type = 1
##
##[Subnet Address Range : "Subnet Server.VLAN19.BDOK"]
## Start Address = 172.29.11.0
## End Address = 172.29.11.0
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 99
##
##[Subnet Address Range : "LAN.VLAN19.BDOK"]
## Start Address = 172.29.11.50
## End Address = 172.29.11.250
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 3
## DNS Update Option = 2
$RegexOptions = [System.Text.RegularExpressions.RegexOptions]
$options = ($RegexOptions::Multiline -bor $RegexOptions::IgnoreCase)
^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\n\t(?<lines>.+?))*$
$reg = new-object System.Text.RegularExpressions.Regex($regex, $options)
$matches = $reg.Matches($tabFile)
$matches.Count
$matches | Foreach-Object {
$_.Groups["name"].Value
$_.Groups["desc"].Value
$_.Groups["lines"].Captures | foreach-Object {
$_.Value
}
}
I've tested this regular expression in a program called the regulator and it
works perfectly. Unfortunately when running it in powershell it does not
match anything. If I remove the $ it does match some of what i want but not
all. Is this a bug?
--
**********************
Jacob
Jacob,

The '$' at the end of your expression is not necessary, and you are
missing a '\r' before your "lines" group:

^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\r\n\t(?<lines>.
+?))*

I hope this helps.

Jeff
unknown
2007-11-28 06:06:00 UTC
Permalink
Hi Jeff,
Thanks for your reply. As it turns out the program I was using called
Regulator was working when it shouldn't have been. The final regex was

\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\r\n\t(?<lines>.+?))*\r\n\r\n
--
**********************
Jacob
Post by Jeff
Post by unknown
$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))
##[Subnet : "172.29.11.0(VLAN19)"]
## Subnet Address = 172.29.11.0
## Subnet Mask = 255.255.255.0
## Lease Time = 259200
## Config Options = 00 00 00 00 03 04 AC 1D 0B 01
## Zone Reference = bdokendalls_com_au.BDOK
## Domain Name = bdokendalls.com.au
## Subnet Type = 1
##
##[Subnet Address Range : "Subnet Server.VLAN19.BDOK"]
## Start Address = 172.29.11.0
## End Address = 172.29.11.0
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 99
##
##[Subnet Address Range : "LAN.VLAN19.BDOK"]
## Start Address = 172.29.11.50
## End Address = 172.29.11.250
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 3
## DNS Update Option = 2
$RegexOptions = [System.Text.RegularExpressions.RegexOptions]
$options = ($RegexOptions::Multiline -bor $RegexOptions::IgnoreCase)
^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\n\t(?<lines>.+?))*$
$reg = new-object System.Text.RegularExpressions.Regex($regex, $options)
$matches = $reg.Matches($tabFile)
$matches.Count
$matches | Foreach-Object {
$_.Groups["name"].Value
$_.Groups["desc"].Value
$_.Groups["lines"].Captures | foreach-Object {
$_.Value
}
}
I've tested this regular expression in a program called the regulator and it
works perfectly. Unfortunately when running it in powershell it does not
match anything. If I remove the $ it does match some of what i want but not
all. Is this a bug?
--
**********************
Jacob
Jacob,
The '$' at the end of your expression is not necessary, and you are
^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\r\n\t(?<lines>.
+?))*
I hope this helps.
Jeff
Keith Hill [MVP]
2007-11-28 06:39:06 UTC
Permalink
Post by unknown
$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))
##[Subnet : "172.29.11.0(VLAN19)"]
## Subnet Address = 172.29.11.0
## Subnet Mask = 255.255.255.0
## Lease Time = 259200
## Config Options = 00 00 00 00 03 04 AC 1D 0B 01
## Zone Reference = bdokendalls_com_au.BDOK
## Domain Name = bdokendalls.com.au
## Subnet Type = 1
##
##[Subnet Address Range : "Subnet Server.VLAN19.BDOK"]
## Start Address = 172.29.11.0
## End Address = 172.29.11.0
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 99
##
##[Subnet Address Range : "LAN.VLAN19.BDOK"]
## Start Address = 172.29.11.50
## End Address = 172.29.11.250
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 3
## DNS Update Option = 2
$RegexOptions = [System.Text.RegularExpressions.RegexOptions]
$options = ($RegexOptions::Multiline -bor $RegexOptions::IgnoreCase)
^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\n\t(?<lines>.+?))*$
$reg = new-object System.Text.RegularExpressions.Regex($regex, $options)
$matches = $reg.Matches($tabFile)
$matches.Count
$matches | Foreach-Object {
$_.Groups["name"].Value
$_.Groups["desc"].Value
$_.Groups["lines"].Captures | foreach-Object {
$_.Value
}
}
I've tested this regular expression in a program called the regulator and it
works perfectly. Unfortunately when running it in powershell it does not
match anything. If I remove the $ it does match some of what i want but not
all. Is this a bug?
The newline that you have inserted in your regular expression string (via
the @" "@ here string) is just a `n char. If you were to change this:

$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))

to

$tabFile = [string]::Join("`n", (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))

You would get further. Or you could change the regex:

224> $regex = [regex]'(?im)^\[(?<name>[^:]+) :
"(?<desc>[^"]*)"\]\r\n(?:\t(?<lines>.+)(\z|\r\n(?!^$)))*'
225> $regex.Matches($tabfile) | %{$OFS="`n ";"$($_.Groups['name'].Value)
: $($_.Groups['desc'].Value) : $($_.Groups['lines'].Captures)"}
Subnet : 172.29.11.0(VLAN19) : Subnet Address = 172.29.11.0
Subnet Mask = 255.255.255.0
Lease Time = 259200
Config Options = 00 00 00 00 03 04 AC 1D 0B 01
Zone Reference = bdokendalls_com_au.BDOK
Domain Name = bdokendalls.com.au
Subnet Type = 1
Subnet Address Range : Subnet Server.VLAN19.BDOK : Start Address =
172.29.11.0
End Address = 172.29.11.0
DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
Range Type = 99
Subnet Address Range : LAN.VLAN19.BDOK : Start Address = 172.29.11.50
End Address = 172.29.11.250
DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
Range Type = 3
DNS Update Option = 2

Rather than mess with the RegexOptions enum I would just use (?im) at the
beginning of the regex. It's a lot less to type. :-) I also recommended
using single quoted strings unless you need PowerShell variable
substitution. Otherwise you have to worry about escaping certain characters
that have special meaning to PowerShell like $.

--
Keith
unknown
2007-11-28 08:53:02 UTC
Permalink
Will do, thanks for the feedback!
--
**********************
Jacob
Post by Keith Hill [MVP]
Post by unknown
$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))
##[Subnet : "172.29.11.0(VLAN19)"]
## Subnet Address = 172.29.11.0
## Subnet Mask = 255.255.255.0
## Lease Time = 259200
## Config Options = 00 00 00 00 03 04 AC 1D 0B 01
## Zone Reference = bdokendalls_com_au.BDOK
## Domain Name = bdokendalls.com.au
## Subnet Type = 1
##
##[Subnet Address Range : "Subnet Server.VLAN19.BDOK"]
## Start Address = 172.29.11.0
## End Address = 172.29.11.0
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 99
##
##[Subnet Address Range : "LAN.VLAN19.BDOK"]
## Start Address = 172.29.11.50
## End Address = 172.29.11.250
## DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
## Range Type = 3
## DNS Update Option = 2
$RegexOptions = [System.Text.RegularExpressions.RegexOptions]
$options = ($RegexOptions::Multiline -bor $RegexOptions::IgnoreCase)
^\[(?<name>[^\r\n]+)\ :\ "(?<desc>[^"\r\n]*)"\](?:\n\t(?<lines>.+?))*$
$reg = new-object System.Text.RegularExpressions.Regex($regex, $options)
$matches = $reg.Matches($tabFile)
$matches.Count
$matches | Foreach-Object {
$_.Groups["name"].Value
$_.Groups["desc"].Value
$_.Groups["lines"].Captures | foreach-Object {
$_.Value
}
}
I've tested this regular expression in a program called the regulator and it
works perfectly. Unfortunately when running it in powershell it does not
match anything. If I remove the $ it does match some of what i want but not
all. Is this a bug?
The newline that you have inserted in your regular expression string (via
$tabFile = [string]::Join([environment]::NewLine, (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))
to
$tabFile = [string]::Join("`n", (Get-Content
"C:\data\!!sandbox\dhcp\dhcp3tab"))
"(?<desc>[^"]*)"\]\r\n(?:\t(?<lines>.+)(\z|\r\n(?!^$)))*'
225> $regex.Matches($tabfile) | %{$OFS="`n ";"$($_.Groups['name'].Value)
: $($_.Groups['desc'].Value) : $($_.Groups['lines'].Captures)"}
Subnet : 172.29.11.0(VLAN19) : Subnet Address = 172.29.11.0
Subnet Mask = 255.255.255.0
Lease Time = 259200
Config Options = 00 00 00 00 03 04 AC 1D 0B 01
Zone Reference = bdokendalls_com_au.BDOK
Domain Name = bdokendalls.com.au
Subnet Type = 1
Subnet Address Range : Subnet Server.VLAN19.BDOK : Start Address =
172.29.11.0
End Address = 172.29.11.0
DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
Range Type = 99
Subnet Address Range : LAN.VLAN19.BDOK : Start Address = 172.29.11.50
End Address = 172.29.11.250
DHCP Server Reference = "DHCP_NWC-BNE-B.BRIS.BDOK"
Range Type = 3
DNS Update Option = 2
Rather than mess with the RegexOptions enum I would just use (?im) at the
beginning of the regex. It's a lot less to type. :-) I also recommended
using single quoted strings unless you need PowerShell variable
substitution. Otherwise you have to worry about escaping certain characters
that have special meaning to PowerShell like $.
--
Keith
Loading...