有没有更好的方法将所有控制字符转换为PowerShell 5中的实体?

时间:2016-12-08 06:17:03

标签: powershell

上下文:Azure,Windows Server 2012,PowerShell 5

我有以下代码将所有控制字符(除了\ x20本身之外的ascii和unicode空格)转换为它们的&符号哈希等价物。

function ConvertTo-AmpersandHash {
  param ([Parameter(Mandatory)][String]$Value)
  # there's got to be a better way of doing this. 
  $AMPERHASH = '&#'
  $SEMICOLON = ';'
  for ($i = 0x0; $i -lt 0x20; $i++) { 
    $value = $value -replace [char]$i,($AMPERHASH + $i + $SEMICOLON) 
  }
  for ($i = 0x7f; $i -le 0xa0; $i++) { 
    $value = $value -replace [char]$i,($AMPERHASH + $i + $SEMICOLON) 
  }
  return $Value 
}

从嵌入式评论中可以看出,我确信有更好的方法可以做到这一点。就目前而言,每个传入的字符串会执行大约65次迭代。正则表达式会更好/更快地运作吗?

LATER

 -replace '([\x00-\x1f\x7f-\xa0])',('&#' + [byte][char]$1  + ';')

看起来很有希望,但1美元一直在评估为零,一直给我�

以后

认为-replace无法在内部迭代,我想出了

$t = [char]0 + [char]1 + [char]2 + [char]3 + [char]4 + [char]5 + [char]6
$r = '([\x00-\x1f\x7f-\xa0])'
while ($t -match [regex]$r) {
  $t = $t -replace [regex]$r, ('&#' + [byte][char]$1  + ';')
}
echo $t

然而,我还是得到了

�������

最后

function ConvertTo-AmpersandHash {
  param ([Parameter(Mandatory)][String]$Value)
  $AMPERHASH = '&#'
  $SEMICOLON = ';'
  $patt = '([\x00-\x1f\x7f-\xa0]{1})'
  while ($Value -match [regex]$patt) {
    $Value = $Value -replace $Matches[0], ($AMPERHASH + [byte][char]$Matches[0]  + $SEMICOLON)
  }
  return $Value 
}

效果更好。更快。对此有何进展?

3 个答案:

答案 0 :(得分:2)

我的问题有点不清楚,可能与What is the best way to escape HTML-specific characters in a string (PowerShell)?重复。

如果您明确说明了您拥有的确切字符串以及您希望它转换为什么字符串,那就太好了。一个人必须阅读代码才能猜到。

我猜这些功能中的一个或多个会做你想做的事情:

$a = "http://foo.org/bar?baz & also <value> conversion"
"a"
$a

$b = [uri]::EscapeDataString($a)
"b"
$b
$c = [uri]::UnescapeDataString($b)
"c"
$c

Add-Type -AssemblyName System.Web
$d = [System.Web.HttpUtility]::HtmlEncode($a)
"d"
$d
$e = [System.Web.HttpUtility]::HtmlDecode($d)
"e"
$e

给出:

a
http://foo.org/bar?baz & also <value> conversion
b
http%3A%2F%2Ffoo.org%2Fbar%3Fbaz%20%26%20also%20%3Cvalue%3E%20conversion
c
http://foo.org/bar?baz & also <value> conversion
d
http://foo.org/bar?baz &amp; also &lt;value&gt; conversion
e
http://foo.org/bar?baz & also <value> conversion

答案 1 :(得分:2)

Kory Gill对图书馆电话的回答肯定是一种更好的方法,但为了解决您的正则表达式问题,您无法使用-replace运算符评估代码中的代码。

要做到这一点,您需要使用.Net regex replace method,并传递一个脚本块来评估替换,它接受匹配的参数。 e.g。

PS C:\> [regex]::Replace([string][char]2,
                         '([\x00-\x20\x7f-\xa0])',
                         {param([string]$m) '&#' + [byte][char]$m + ';'})
&#2;

答案 2 :(得分:1)

我有一个小功能可以帮助我按照我的要求进行更换:

$ SpecChars 是所有将替换为

的字符
Function Convert-ToFriendlyName

{param ($Text)

# Unwanted characters (includes spaces and '-') converted to a regex:

$SpecChars =  '\', ' ','\\'

$remspecchars = [string]::join('|', ($SpecChars | % {[regex]::escape($_)}))

# Convert the text given to correct naming format (Uppercase)

$name = (Get-Culture).textinfo.totitlecase(“$Text”.tolower())

# Remove unwanted characters

$name = $name -replace $remspecchars, ""

$name

}

示例:Convert-ToFriendlyName&#34;我的\ Name \ isRana \ Dip&#34;将导致我&#34; MyNameIsranaDip&#34;。

希望它对你有所帮助。