0

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!

6
  • What have you tried so far? You can use a combination of Trim and StartWith() Commented Dec 14, 2021 at 8:58
  • I tried a regex replace on 1st occurance, but it doesn't work for the exact scenario I gave above since it replaces #abc with #xyz instead of ignoring that and replacing the next one. As for Trim and StartsWith wouldn't that only work if the whitespace was at the start of the string and not in the next line? Commented Dec 14, 2021 at 9:07
  • while ignoring any whitespaces that might precede it Can you clarify? Commented Dec 14, 2021 at 9:47
  • As in I still want it to replace if there is a whitespace before my string so in the above example my 2nd line has " abc". I still want it to replace regardless of whether my 2nd line had "abc" or " abc" Commented Dec 14, 2021 at 10:02
  • So is it possible that the second line has no whitespace in front? Commented Dec 14, 2021 at 10:02

2 Answers 2

2

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

Comments

0

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

2 Comments

The problem is that it is replacing the first instance in my given string which is #abc and not the next one where the new line starts with abc (ignoring whitespace) This is what I tried. $test = '#ABC ABC DEF ABC' [regex]$pattern = "ABC" $pattern.replace($test, "xyz", 1)
and the replace command was specified to alter the first instance only. How to Use PowerShell Replace to Replace Text [Examples] <adamtheautomator.com/powershell-replace>

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.