Home > OS >  Powershell replace first instance of word starting on new line
Powershell replace first instance of word starting on new line

Time:12-15

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

multiline text replace

  • Related