I’m building a little app that is driven by an XML configuration file. I need to substitute variables from the XML with a random name or a keyword from another source, so I used $Keyword and $MaleName and $FemaleName.

Look at this code, and see if you can spot the bug. Every single text field that I passed was showing that it contains a characterName (i.e. either $MaleName or $FemaleName.

Function IsTextViolation($text) 
{
    $isViolation = $false 
    $containsCharacterName = $false 
    if ($text.Contains("$MaleName") -or $text.Contains("$FemaleName")) 
       {
          $containsCharacterName = $true 
       }
     Write-Host "containsCharacterName=$containsCharacterName" 

     if ($text.Contains("$Keyword") -and $containsCharactername) 
        {
           $isViolation = $true 
        }
      return $isViolation 
}
cls
Write-Host "1 $(IsTextViolation('Test 1 $Keyword') )"
Write-Host "2 $(IsTextViolation('Test 1 $MaleName') )"
Write-Host "3 $(IsTextViolation('Test 1 $FemaleName') )"
Write-Host "4 $(IsTextViolation('$MaleName Test 1 $Keyword') )"
Write-Host "5 $(IsTextViolation('Test 1 $FemaleName $Keyword') )"

So here is the issue… I chose to use $ sign as prefix to my variable, I could have used % or @ or any other symbol, but with Powershell on the brain, I chose the dollar sign. Well, when you put $MaleName in double quotes, it was substituting the value of $MaleName, which is apparently null ($null). And thus the match was always true. I had two solutions, either 1) use single quotes instead of double quotes, or 2) prefix with the escape character (the grave accent mark like this – (“`$MaleName”). I chose the first, and here is the corrected code.

Corrected Code:

Function IsTextViolation($text) 
{
    $isViolation = $false 
    $containsCharacterName = $false 
    if ($text.Contains('$MaleName') -or $text.Contains('$FemaleName')) 
       {
          $containsCharacterName = $true 
       }
     Write-Host "containsCharacterName=$containsCharacterName" 

     if ($text.Contains('$Keyword') -and $containsCharactername) 
        {
           $isViolation = $true 
        }
      return $isViolation 
}


cls
Write-Host "1 $(IsTextViolation('Test 1 $Keyword') )"
Write-Host "2 $(IsTextViolation('Test 1 $MaleName') )"
Write-Host "3 $(IsTextViolation('Test 1 $FemaleName') )"
Write-Host "4 $(IsTextViolation('$MaleName Test 1 $Keyword') )"
Write-Host "5 $(IsTextViolation('Test 1 $FemaleName $Keyword') )"

Filed under: Powershell