【问题标题】:How to compare strings that have an ampersand in them in PowerShell如何在 PowerShell 中比较包含与号的字符串
【发布时间】:2017-04-17 17:01:28
【问题描述】:

我正在使用 PowerShell 来比较两个包含与号 (&) 的字符串(即字符串“Policies & Procedures”)。

无论我尝试什么,我都无法让这些字符串匹配。我尝试修剪字符串以消除额外的空格。我尝试将字符串用单引号和双引号(以及两者的组合)括起来:

"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 都打印到屏幕上,它们是相同的。如果字符串中没有 & 符号,则此函数有效。如果有 & 符号,此功能将失败。这就是我知道与号是问题的方式。

【问题讨论】:

  • 刚刚尝试了下面的代码,它按预期返回了$true,你能显示生成字符串的代码吗? $term1 = 'Policies & Procedures'$term2 = 'Policies & Procedures'$term1 -eq $term2
  • 同样的事情,为我返回$True
  • & 符号是 not a special character in PowerShell strings,是什么让您将其称为导致问题的特定事物?
  • 我认为我的问题不应该被降级,因为它确实揭示了&符号之间的区别

标签: string powershell compare


【解决方案1】:

这是known quirk

您需要注意两种类型的 & 符号 使用 SharePoint 分类法

我们最喜欢和最喜爱的

  • & ASCII 码:38

还有骗子

  • ASCII 码:65286

Nick Hobbs 阅读this article 之后,它变得很明显 当您创建一个术语时,它会将38 与符号替换为 65286 和号。

如果您想与您的 原始来源(电子表格、数据库等),因为它们不再是 一样。

如 Nick 的文章中所述,您可以使用 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
}

【讨论】:

  • 很难将 65286 视为 ASCII 代码,因为 ASCII 是 7 位编码。 65286 值是全宽 AMPERSAND 的 Unicode 代码点。
  • 这是一个比我的更优雅的解决方案。感谢您发布此信息!
【解决方案2】:

在将两个字符串都转换为 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
}

【讨论】:

    猜你喜欢
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 2021-12-21
    • 1970-01-01
    • 2015-04-17
    相关资源
    最近更新 更多