So lets say I have a multi line string as below.
#abc
abc def
abc
I want to only replace the first instance of abc that starts on a new line with xyz while ignoring any whitespaces that might precede it (like in the above example)
So my replaced string should read
#abc
xyz def
abc
Not very good at regex so would appreciate suggestions. Thanks!
CodePudding user response:
To do that, you need a regular expression that anchors to the beginning of a line, allows for multiple leading whitespaces and uses a word boundary to make sure you do not replace part of a larger string.
$multilineText = @"
#abc
abc def
abc
"@
$toReplace = 'abc'
$replaceWith = 'xyz'
# create the regex string.
# Because the example `abc` in real life could contain characters that have special meaning in regex,
# you need to escape these characters in the `$toReplace` string.
$regexReplace = '(?m)^(\s*){0}\b' -f [regex]::Escape($toReplace)
# do the replacement and capture the result to write to a new file perhaps?
$result = ([regex]$regexReplace).Replace($multilineText, "`$1$replaceWith", 1)
# show on screen
$result
The above works Case-Sensitive, but if you do not want that, simply change (?m)
into (?mi)
in the $regexReplace
definition.
Output:
#abc
xyz def
abc
Regex details:
(?m) Match the remainder of the regex with the options: ^ and $ match at line breaks (m)
^ Assert position at the beginning of a line (at beginning of the string or after a line break character)
( Match the regular expression below and capture its match into backreference number 1
\s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
* Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
){0}
\b Assert position at a word boundary
Special Characters in Regex
Char | Description | Meaning |
---|---|---|
\ | Backslash | Used to escape a special character |
^ | Caret | Beginning of a string |
$ | Dollar sign | End of a string |
. | Period or dot | Matches any single character |
| | Vertical bar or pipe symbol | Matches previous OR next character/group |
? | Question mark | Match zero or one of the previous |
* | Asterisk or star | Match zero, one or more of the previous |
Plus sign | Match one or more of the previous | |
( ) | Opening and closing parenthesis | Group characters |
[ ] | Opening and closing square bracket | Matches a range of characters |
{ } | Opening and closing curly brace | Matches a specified number of occurrences of the previous |
CodePudding user response:
The 1 just replaces the first instance of 'abc' with 'xyz' within a string.
Write-Host "Replace Example One" -ForegroundColor Yellow -BackgroundColor DarkGreen
$test = " abc def abc "
[regex]$pattern = "abc"
$pattern.replace($test, "xyz", 1)
Write-Host "Replace Example Two" -ForegroundColor Green -BackgroundColor Blue
$test = Get-Content "c:\test\text.txt"
[regex]$pattern = "abc"
$x = $pattern.replace($test, "xyz", 1)
Write-Host $x
Write-Host "Replace Example Three" -ForegroundColor White -BackgroundColor Red
$multilineText = @"
#abc
abc def
abc
"@
[regex]$pattern = "abc"
$y = $pattern.replace($multilineText, "xyz", 1)
Write-Host $y