2015-03-25 97 views
1

输入一个字母数字字符串,发送到较低值,然后进行求值。然后,每个第三个字母需要大写并返回到一个字符串。数字/字母的位置并不总是相同的。连接字符数组元素

样品输入处理:

$in = read-host "value in" 
$var1 = $in.tolower() 

所以我给了,可以用来作为一个例子两个变量

$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 

的问题是,循环显示每个相应的字符要上,但在末尾显示$val时不会进行更改。

回答

2

看起来你正在处理范围问题。在ForEach循环中,变量位于不影响它们来自的数组的范围内。没有完全重写的简单修改就是简单地添加一个新变量,并将其设置为您的ForEach循环的输出,然后让ForEach循环输出$n而不是回显它(或除此之外)。

现在,只要我可以告诉你的If说法是错误的和正确的字母不事实上被资本化,但抛开这至少可以让你的代码的功能,只要你想:

$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 '' 

就个人而言,我会使用Switch命令而不是ForEach命令和所有这些If语句。喜欢的东西:

$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 '' 
+0

我拿起这有三个方面的最佳答案:第一个选项是最接近我的原代码,我不知道你可以做一个循环一个变量(天才!),并且您使用开关的建议是我所使用的。 – MrSchism 2015-04-03 11:24:34

1

您正在修改$ n的值,但不是原始数组$ val。

尝试......

$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 
1

这是另一种方法。 如果你想在String中得到结果,你必须像这样创建新的String对象。

$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 
1

另一种选择:

$var1 = '1ab23c4def56' 

$i=0 
$var1 = 
$([string[]][char[]]$var1 | 
foreach { 
if (++$i %3) { $_ } 
    else { $_.ToUpper() } 
}) -join '' 

$var1 
+0

不错的一个。作为一种变体,您可以删除子表达式和'-join'操作并执行'$ OFS =''; “$ var1”'代替。 – 2015-03-25 13:32:39

+1

@Ansgar Weichars - 谢谢!我通常尽量避免与$ OFS混淆。如果我这样做,我通常会将这种改变分离到它自己的范围内,以便在我完成改变之前恢复到之前的状态。 – mjolinor 2015-03-25 13:44:43