6

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.

3 Answers 3

5

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
Sign up to request clarification or add additional context in comments.

2 Comments

I prefer the escape solution. Another solution would be a here string like "1. First line 2. Second line 3. Third line" -replace '([2-9]\. )', @' $1 '@ (note there's a crlf before $1!)
Thanks, I get it now. The first method worked well for me. It's strange that the -Replace command will find a newline char within single quotes as the thing to search for.
1

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]+\. )'

1 Comment

Makes sense. I ended up achieving the same by doing the replace twice, like this: $theString = $theString -replace '([1-9][0-9]\. )', $("`n"+'$1') ...and then $theString = $theString -replace '([2-9]\. )', $("`n"+'$1')
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.