2016-12-02 135 views
0

我正在使用PowerShell比较两个字符串(&)(即字符串“Policies & Procedures”)中的两个字符串。如何比较PowerShell中具有与符号的字符串

无论我尝试什么,我都无法获取这些字符串来匹配。我已经尝试修剪字符串以摆脱额外的空白。我已经试过包装在单,双引号的字符串(和两者的结合):

"Policies & Procedures" 
'Policies & Procedures' 
"'Policies & Procedures'" 

我使用比较字符串的代码是:

if ($term1 -eq $term2) { 
    do something 
} 

视觉检查字符串 - 它们是相同的,但是if语句从不计算为真。有没有办法比较这两个字符串,以便它评估为真?

编辑

在我做这个字符串的上下文比较正在寻找在SharePoint网站上的分类术语名称。这里是我使用的代码:

function getTerm($termName) { 

    foreach($term in $global:termset.Terms) { 
    $termTrimmed = $term.Name.trim() 
    Write-Host "term name = $termTrimmed" -foregroundcolor cyan 
    if ($termTrimmed -eq $termName) { 
     return $term 
    } 
    } 
    return null 
} 

我已经打印term.Name和termName到屏幕,它们是相同的。如果字符串中没有&符号,则此函数可用。如果有&符号,则此函数失败。这是我知道&符号是问题的方式。

+0

刚刚尝试了下面的代码,并按预期的方式返回了'$ true',您能显示正在生成字符串的代码吗? '$字词1 = '政策及Procedures'' '$词条2 =' 政策及Procedures'' '$字词1当量$ term2' –

+0

同样的事,返回'我$ TRUE'。 – 4c74356b41

+0

&符号[不是PowerShell字符串中的特殊字符](https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_quoting_rules),是什么让你称呼它作为导致问题的特殊事物? – TessellatingHeckler

回答

1

这是一个known quirk

有两种类型的&符号的,你需要知道,当 与SharePoint分类玩

我们最喜欢和最被爱

  • & ASCII编号:38

而冒名顶替

  • ASCII编号:65286

通过Nick Hobbs阅读this article后,很明显 ,当你创建一个术语它取代了38符号与 65286&符号。

如果您想与您的 原始来源(电子表格,数据库等)进行比较,因为它们不再是 相同,这会变成问题。

正如尼克的文章详细介绍,您可以使用 TaxonomyItem.NormalizeName方法来创建 你的字符串的“分类”版本比较:

试试这个(真实的SharePoint未测试):

function getTerm($termName) 
{ 
    foreach($term in $global:termset.Terms) { 
    $termNormalized = [Microsoft.SharePoint.Taxonomy.TaxonomyItem]::NormalizeName($term.Name) 
    if ($termNormalized -eq $termName) { 
     return $term 
    } 
    } 
    return null 
} 
+0

由于ASCII是7位编码,因此很难将'65286'看作ASCII码。 “65286”的值是全宽安培码的Unicode代码点。 – lit

+0

这是比我更优雅的解决方案。感谢张贴这! – user5013

1

将两个字符串转换为char数组并将&符号的unicode值进行比较后,问题就会显示出来。搜索字符串中使用的&符号的值为38,而从SharePoint术语库返回的&符号的值为65286(称为完整&符号,虽然看起来与屏幕上的常规符号相同)。

解决方案是编写我自己的字符串比较函数,并考虑到与符号值的差异。下面是代码:

function getTerm($termName) { 

    $searchChars = $termName.toCharArray() 
    $size = $searchChars.Count; 
    foreach($term in $global:termset.Terms) { 
    $match = $True 
    $chars = $term.Name.trim().toCharArray() 
    if ($size -eq $chars.Count) { 
     for ($i = 0; $i -lt $size; $i++) { 
     if ($searchChars[$i] -ne $chars[$i]) { 
      # handle the difference between a normal ampersand and a full width ampersand 
      $charCode1 = [int] $searchChars[$i] 
      $charCode2 = [int] $chars[$i] 
      if ((($charCode1 -eq 38) -or ($charCode1 -eq 65286)) -and (($charCode2 -eq 38) -or ($charCode2 -eq 65286))) { 
      continue 
      } else { 
      $match = $False 
      break 
      } 
     } 
     } 
    } else { 
     $match = $False 
    } 
    if ($match -eq $True) { 
     return $term 
    } 
    } 
    return $null 
}