2015-03-25 101 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