Reputation: 283
I am trying to return the sections of an INI file as an array of captures using a regular expression:
\[[^\]\r\n]+](?:\r?\n(?:[^\[\r\n].*)?)*
This works in just about every regex checker I have tried, including one using .NET, but when I try it in my program, it only selects the section headers, not the bodies.
I'm working in Powershell, but I'm explicitly creating a Regex object using New-Object, not the built-in -match operator. I'm at a bit of a loss since it works outside my environment but not inside it.
Update: Ansgar reminds me that I should have shown my code, so here it is.
$IniRegex = New-Object System.Text.RegularExpressions.Regex("\[[^\]\r\n]+](?:\r?\n(?:[^\[\r\n].*)?)*")
$TestIni = Get-Content "C:\Test.ini"
$SectionsMatches = $IniRegex.Matches($TestIni)
$SectionsMatches.Count
$SectionsMatches[0].Captures[0].ToString()
$SectionsMatches[1].Captures[0].ToString()
The Test.ini file contains some sample settings:
[Test0]
Setting0=0
Setting1=1
[Test1]
Setting2=2
Setting3=3
The output from the code is:
2
[Test0]
[Test1]
Upvotes: 3
Views: 479
Reputation: 3163
If you're on PowerShell 3 or higher, add -Raw to the end of Get-Content. By default, Get-Content returns an array of strings, with one element corresponding to one line. But you want to match against a single string:
$IniRegex = New-Object System.Text.RegularExpressions.Regex("\[[^\]\r\n]+](?:\r?\n(?:[^\[\r\n].*)?)*")
$TestIni = Get-Content "C:\Test.ini" -Raw
$SectionsMatches = $IniRegex.Matches($TestIni)
$SectionsMatches.Count
$SectionsMatches[0].Captures[0].ToString()
$SectionsMatches[1].Captures[0].ToString()
If you're on v2, you can do this instead:
$TestIni = (Get-Content "C:\Test.ini") -join ''
Also, you can shorten the line where you create the regex quite a bit, by using the [regex] type accelerator:
$IniRegex = [regex]"\[[^\]\r\n]+](?:\r?\n(?:[^\[\r\n].*)?)*"
Upvotes: 2