Reputation: 43
An alphanumeric string is input, sent to lower, then evaluated. Then, every third letter needs to be capitalized and returned to a string. The number/letter positions are not always the same.
Sample input handling:
$in = read-host "value in"
$var1 = $in.tolower()
So I've given two variables that can be used as an example
$var1 = 1ab23c4def56
# $var1 = a123bcd45e6f # alternate $var1 for example purposes
$val = ($var1).ToCharArray()
foreach ($n in $val){
if ($n -notmatch "[0-9]"){
$alfaNo++
if ($alfaNo -eq 4){
$o = $([char]::ToUpper($n))
$alfaNo = 0
$n = $o
}
echo $n
}
else {echo $n}
}
$val
The issue is that the loop shows each appropriate character going to upper, but the change isn't made when $val
displayed at the end.
Upvotes: 1
Views: 519
Reputation: 68243
Another option:
$var1 = '1ab23c4def56'
$i=0
$var1 =
$([string[]][char[]]$var1 |
foreach {
if (++$i %3) { $_ }
else { $_.ToUpper() }
}) -join ''
$var1
Upvotes: 1
Reputation: 36287
Looks like you're dealing with Scope issues. While in the ForEach
loop the variables are in a scope that don't affect the array that they come from. A simple modification without a complete re-write would be to simply add a new variable, and set it to be the output of your ForEach
loop, and then have the ForEach
loop output $n
instead of echoing it (or in addition to).
Now, so far as I can tell your If
statement is just wrong and the correct letters are not in fact being capitalized, but that aside this at least lets your code function as you want:
$var1 = "1ab23c4def56"
# $var1 = a123bcd45e6f # alternate $var1 for example purposes
$val = ($var1).ToCharArray()
$alfaNo = 0
$NewVal = foreach ($n in $val){
if ($n -notmatch "[0-9]"){
$alfaNo++
if ($alfaNo -eq 4){
$o = $([char]::ToUpper($n))
$alfaNo = 0
$n = $o
}
}
$n
}
$newval -join ''
Personally I'd use a Switch
command instead of a ForEach
with all those If
statements. Something like:
$var1 = "1ab23c4def56"
# $var1 = a123bcd45e6f # alternate $var1 for example purposes
$inc = 0
$NewVal = Switch($var1 -Split ''){
{$_ -match "\d"} {$_;continue}
{$_ -match "[a-z]" -and $inc -lt 2} {$_;$inc++;continue}
{$_ -match "[a-z]"} {$inc = 0;[char]::toupper($_)}
}
$NewVal -join ''
Upvotes: 2
Reputation: 839
This is another approach. If you want the results in String, you have to create new String object like this.
$var1 = '1ab23c4def56'
$val = ($var1).ToCharArray()
for( $n=0 ; $n -lt $val.length ; $n++)
{
if( (($n % 3) -eq 2) -AND ($val[$n] -match "[a-z]") )
{
$val[$n] = [char]::ToUpper($val[$n])
}
}
$var1 = New-Object System.String ($val,0,$val.Length)
$var1
Upvotes: 1
Reputation: 4454
You're modifying the value of $n but not the original array $val.
Try this...
$var1 = "1ab23c4def56"
# $var1 = a123bcd45e6f # alternate $var1 for example purposes
$val = ($var1).ToCharArray()
$alfaNo = 0
for($i=0;$i -le $val.Length;$i++){
if ($val[$i] -notmatch "[0-9]"){
$alfaNo++
if ($alfaNo -eq 3){
$val[$i] = $([char]::ToUpper($val[$i]))
$alfaNo = 0
}
echo $val[$i]
}
else {echo $val[$i]}
}
$val
Upvotes: 1