'PowerShell - Inserting newline char in string during regex replace
I'm trying to search a string for some numbers and insert a new line before each, not including the first one.
I don't seem to be able to use the traditional regex \n char to insert a newline. If I use the PowerShell escape character, the regex variable from the set is ignored.
For a given source string of
$theString = "1. First line 2. Second line 3. Third line"
What I want is:
1. First Line 2. Second Line 3. Third line
So I tried this regex to find the numbers 2 to 9 followed by a period and a space:
$theString = $theString -replace '([2-9]\. )','\n$1'
but that yields:
1. First line\n2. Second line\n3. Third line
So I tried using the PowerShell escape character for a newline and put it inside double inverted commas:
$theString = $theString -replace '([2-9]\. )',"`n$1"
but that yields:
1. First Line Second Line Third line
I tried using \r
, \r\n
, \`r
, \`r\`n
, etc. trying to force the linebreak, but can't get it to happen without losing the ability to include the current regex variable.
Solution 1:[1]
The problem is caused as $
is used both for ordinary Powershell variables and capture groups. In order to process it as a capture group identifier, single quotes '
are needed. But single quote tells Powershell not to interpret the newline escape as a newline but literal `n
.
Catenating two differently quoted strings does the trick. Like so,
$theString -replace '([2-9]\. )', $("`n"+'$1')
1. First line
2. Second line
3. Third line
As an alternative, use double quotes "
and escape the dollar. Like so,
$theString -replace '([2-9]\. )', "`n`$1"
1. First line
2. Second line
3. Third line
Yet another an alternative (thanks to Lieven) uses here-strings. A here-string contains a newline. Maybe a variable makes it easier to use. Like so,
$repl = @'
$1
'@
$theString -replace '([2-9]\. )', $repl
1. First line
2. Second line
3. Third line
Solution 2:[2]
To allow any number I'd replace the leading space with a newline and use a positive look ahead to filter on.
$theString = "1. First line 2. Second line 3. Third line 11. Eleventh line"
$thestring -replace ' (?=[1-9]+\. )', "`n"
Sample output:
1. First line
2. Second line
3. Third line
11. Eleventh line
To have an array of strings output, with the same RegEx:
$thestring -split ' (?=[1-9]+\. )'
Solution 3:[3]
Another solution would be:
$theString = "1. First line 2. Second line 3. Third line"
$theString -replace '(\s)([0-9]+\.)',([System.Environment]::NewLine+'$2')
which is actually pretty similar to your second line of code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Lieven Keersmaekers |
Solution 2 | |
Solution 3 | TobyU |