title: Hide passwords in string
body: <p>tl;dr 
  How do I replace the word secret with ******** using regex in these cases:</p>
  
  <pre><code>Password="secret"
  PWD="secret"
  -P secret -i args
  </code></pre>
  
  <p>I'm trying to craft a regex that will detect passwords in strings and replace them with *'s (in a logging function).</p>
  
  <p>I currently have this Powershell function:</p>
  
  <pre><code>function ScrubPasswords {
  param(
      [string]$DirtyText
  )
      # match any case of password="" (or PWD="") (or -P .*)
      $PwdArgRegex=[regex]'(([Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|PWD)=)("[^"]+")'
      $PwdArgRegex.replace($DirtyText,'$1********')
  }
  </code></pre>
  
  <p>Which works just great, it replaces the password between the quotes with 8 *'s.</p>
  
  <p>But I found another string that identifies a password is coming. For sqlcmd.exe the argument list is -U username -P password and I want to scrub the passwords from there.</p>
  
  <p>I tried adding |(-P\s([^\s]+)\s) to the regex but it replaces the entire match string with *'s  (-P thispassword -i otherargs becomes ********-i otherargs; unwantedly stripping out the -P\s and trailing \s).</p>
  
  <p>I'm doing my regex design/test at <a href="https://regex101.com/" rel="nofollow noreferrer">https://regex101.com/</a> and then when I have something that looks good I run it through Powershell_ISE.</p>
  
  <p>The problem I think I have is that I have different numbers of groups on both sides of the 2nd OR "|". I'm going to keep fiddling with the parens to see if I can get the match groups to match on both sides.</p>
  
  <p>I would like some help figuring this out, or maybe there's a better way to approach my goal.</p>
  
  <p>This is my best effort so far:</p>
  
  <pre><code>((([Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|PWD)=)("[^"]+")|(-P\s([^\s]+)\s))
  </code></pre>
  
  <p>With these results:</p>
  
  <pre><code>Match 1
  Full match  23-38   `-P @@@sapwd@@@ `
  Group 1.    23-38   `-P @@@sapwd@@@ `
  Group 2.    787-787 ``
  Group 3.    787-787 ``
  Group 4.    787-787 ``
  Group 5.    23-38   `-P @@@sapwd@@@ `
  Group 6.    26-37   `@@@sapwd@@@`
  Match 2
  Full match  235-250 `-P @@@sapwd@@@ `
  Group 1.    235-250 `-P @@@sapwd@@@ `
  Group 2.    787-787 ``
  Group 3.    787-787 ``
  Group 4.    787-787 ``
  Group 5.    235-250 `-P @@@sapwd@@@ `
  Group 6.    238-249 `@@@sapwd@@@`
  Match 3
  Full match  459-487 `Password="@@@NMApassword@@@"`
  Group 1.    459-487 `Password="@@@NMApassword@@@"`
  Group 2.    459-468 `Password=`
  Group 3.    459-467 `Password`
  Group 4.    468-487 `"@@@NMApassword@@@"`
  Group 5.    787-787 ``
  Group 6.    787-787 ``
  Match 4
  Full match  652-669 `PWD="@@@SAPWD@@@"`
  Group 1.    652-669 `PWD="@@@SAPWD@@@"`
  Group 2.    652-656 `PWD=`
  Group 3.    652-655 `PWD`
  Group 4.    656-669 `"@@@SAPWD@@@"`
  Group 5.    787-787 ``
  Group 6.    787-787 ``
  </code></pre>
  
  <p>Using this <strong>test data</strong>:</p>
  
  <pre><code>=begin data=
  
  Result of sqlcmd -U sa -P @@@sapwd@@@ -i  C:\scripts\BridgepointScriptingLibrary\tmp\StandupScripts\common\000_SQLServer_Post_Install_Script.sql = Changed database context to 'master'.  (5 rows affected)
  
  Preparing to run sqlcmd -U sa -P @@@sapwd@@@ -i 000_SQLServer_Post_Install_Script.sql.
  
  Auth User="@@@NMAusername@@@" Password="@@@NMApassword@@@"
  PathFromBinRoot="SQL Server 2008 R2 SP1 (x64bit).exe" PWD="@@@SAPWD@@@"
  
  =end data=
  </code></pre>