Search code examples
powershellreplacems-wordfindwildcard

How to target only formatted text in Word document, for a Find and Replace process


I would like to edit a Word file using a "Find and Replace" approach (in wildcards mode). I’m exclusively targeting italic and bold characters.
Thus :
"One, two, three."
Should become:
"One, two_italic, three_bold."
Here is my script...

$objWord = New-Object -comobject Word.Application  
$objDoc = $objWord.Documents.Open("D:\before.docx")
$objWord.Visible = $true
$objSelection = $objWord.Selection

$Request = @"
FIND,REPLACE
"<[A-Za-z]*>", "^&_italic"
"<[A-Za-z]*>", "^&_bold"
"@ 

$RequestObjs = ConvertFrom-Csv $Request
$FindItalic = $RequestObjs[0]
$FindBold = $RequestObjs[1]

$ReplaceAll = 2
$FindContinue = 1
$MatchCase = $False
$MatchWholeWord = $True
$MatchWildcards = $True
$MatchSoundsLike = $False
$MatchAllWordForms = $False
$Forward = $True
$Wrap = $FindContinue
$Format = $True

function findAndReplace($x) {
  foreach ($RequestObj in $x){
  #$objSelection.find.replacement.Font.bold = $True
  $b = $objSelection.Find.Execute($($RequestObj.FIND), $MatchCase,
  $MatchWholeWord,$MatchWildcards,$MatchSoundsLike,
  $MatchAllWordForms,$Forward,$Wrap,$Format,$($RequestObj.REPLACE),$ReplaceAll);
}
}

while ($objSelection.find.Font.italic = $True) {
$x = $FindItalic
 findAndReplace($x) 
 break
}

while ($objSelection.find.Font.bold = $True) {
$x = $FindBold
 findAndReplace($x)
 break
 }
 
$FileSaveAs ="D:\after.docx"
$wdFormatWordDefault = 16
$objDoc.SaveAs($FileSaveAs,$wdFormatWordDefault)<br>

But what I get is :
"One, two_italic, three."
It works for the italicized word "two", but not for the bolded word "three"...
Why does the function stop halfway? Your help will be precious !


Solution

  • Got it! Inserting $objSelection.find.Font.bold = $False in between the two while loops did the trick.
    New script :

    $objWord = New-Object -comobject Word.Application  
    $objDoc = $objWord.Documents.Open("D:\before.docx")
    $objWord.Visible = $true
    $objSelection = $objWord.Selection
    
    $Request = @"
    FIND,REPLACE
    "<[A-Za-z]*>", "^&_italic"
    "<[A-Za-z]*>", "^&_bold"
    "@ 
    
    $RequestObjs = ConvertFrom-Csv $Request
    $FindItalic = $RequestObjs[0]
    $FindBold = $RequestObjs[1]
    
    $ReplaceAll = 2
    $FindContinue = 1
    $MatchCase = $False
    $MatchWholeWord = $True
    $MatchWildcards = $True
    $MatchSoundsLike = $False
    $MatchAllWordForms = $False
    $Forward = $True
    $Wrap = $FindContinue
    $Format = $True
    
    function findAndReplace($x) {
      $b = $objSelection.Find.Execute($($x.FIND), $MatchCase,
      $MatchWholeWord,$MatchWildcards,$MatchSoundsLike,
      $MatchAllWordForms,$Forward,$Wrap,$Format,$($x.REPLACE),$ReplaceAll);
     }
        
    while ($objSelection.find.Font.bold = $True) {
    $x = $FindBold
    findAndReplace($x)
    break
    }
    
    ## KEY LINE ##
    $objSelection.find.Font.bold = $False
    
    while  ($objSelection.find.Font.italic =$True) {
    $x = $FindItalic
    findAndReplace($x) 
    break
    }
     
    $FileSaveAs ="D:\after.docx"
    $wdFormatWordDefault = 16
    $objDoc.SaveAs($FileSaveAs,$wdFormatWordDefault)