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.
<pre>
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') )"
</pre>
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:
<pre>
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') )"
</pre>