2015-10-22 47 views
1

我已經按照本文中的優秀的解決方案:PowerShell的正則表達式替換表達式

PowerShell multiple string replacement efficiency

嘗試和規範從Active Directory導入電話號碼。這裏有一個例子:

$telephoneNumbers = @(
     '+61 2 90237534', 
     '04 2356 3713' 
     '(02) 4275 7954' 
     '61 (0) 3 9635 7899' 
     '+65 6535 1943' 
     ) 

# Build hashtable of search and replace values. 
$replacements = @{ 
    ' ' = '' 
    '(0)' = '' 
    '+61' = '0' 
    '(02)' = '02' 
    '+65' = '001165' 
    '61 (0)' = '0' 
} 

# Join all (escaped) keys from the hashtable into one regular expression. 
[regex]$r = @($replacements.Keys | foreach { [regex]::Escape($_) }) -join '|' 

[scriptblock]$matchEval = { param([Text.RegularExpressions.Match]$matchInfo) 
    # Return replacement value for each matched value. 
    $matchedValue = $matchInfo.Groups[0].Value 
    $replacements[$matchedValue] 
} 


# Perform replace over every line in the file and append to log. 
$telephoneNumbers | 
    foreach {$r.Replace($_,$matchEval)} 

我在與在$replacements哈希表的匹配表達式的格式問題。例如,我想匹配所有+61號碼,並替換爲0,並匹配所有其他+號碼並替換爲0011

我試過以下的正則表達式,但他們似乎並不匹配:

'^+61' 

'^+[^61]' 

我在做什麼錯?我試過使用\作爲轉義字符。

+0

感謝您的響應。是的,上面的代碼工作,但會要求我爲所有國家代碼添加散列表條目。理想情況下,我想匹配+61並替換爲0,然後匹配NOT +61並替換爲0011 [國家代碼]。 – Jagged

+0

嗯;你做錯了的是字符類'[]'匹配單個字符,'不是(六個或一個)',並且'[regex] :: EscapeString()'調用將所有內容都轉換爲字符串 - 所以沒有高級正則表達式的命令的工作,而不是尋找字面上開方括號人字形 - 六一一近 - 方括號。你想要的模式是一個負面的前瞻 - '+ +(?!61)' - 加上後面沒有61(不捕獲)。但是你不能通過EscapeString運行它。如果你把EscapeString帶走並在散列表中手工轉義 - 替換代碼無法匹配它... – TessellatingHeckler

+0

我想不出一個好方法 - 也許別人可以,但我會被誘惑爲所有的直接交換替換做這種方法,並且在每個數字上也做一個單獨的'-replace'(\ +(?!61))','0011'。除非你需要做很多這種模式,否則你就不得不重做整件事情,我想。 – TessellatingHeckler

回答

2

我已經對此做了一些重新安排,我不確定它是否適用於您的整個情況,但它爲該示例提供了正確的結果。

我認爲關鍵不是嘗試從哈希表創建一個大的正則表達式,而是循環它並檢查其中的值與電話號碼。

我做的唯一其他更改是將' ',''替換從散列移動到打印替換電話號碼的代碼,因爲您希望它在每種情況下運行。

代碼如下:

$telephoneNumbers = @(
    '+61 2 90237534', 
    '04 2356 3713' 
    '(02) 4275 7954' 
    '61 (0) 3 9635 7899' 
    '+65 6535 1943' 
) 

$replacements = @{ 
    '(0)' = '' 
    '+61' = '0' 
    '(02)' = '02' 
    '+65' = '001165' 
} 

foreach ($t in $telephoneNumbers) { 
    $m = $false 
    foreach($r in $replacements.getEnumerator()) { 
    if ($t -match [regex]::Escape($r.key)) { 
     $m = $true 
     $t -replace [regex]::Escape($r.key), $r.value -replace ' ', '' | write-output 
    } 
    } 
    if (!$m) { $t -replace ' ', '' | write-output } 
} 

給出:

0290237534 
0423563713 
0242757954 
61396357899 
00116565351943 
+0

您還沒有考慮到第四個數字(''61(0)'='0'') –

+0

感謝您的反饋。我會試試這個。 – Jagged