【问题标题】:Replace until a pattern is found in PowerShell替换直到在 PowerShell 中找到模式
【发布时间】:2018-05-03 05:09:34
【问题描述】:

我一直在尝试转换以下字符串:

CN=John Doe,OU=IT,OU=Support,OU=部门,OU=HQ,DC=FR,DC=CONTOSO,DC=COM

到:

FR.CONTOSO.COM

作为第一步,我尝试删除 ",DC" 模式之前的所有内容。

我以为我可以使用不贪心的“.+?”匹配所有内容,直到第一个“,DC”模式:

$str = 'CN=John Doe,OU=IT,OU=Support,OU=Department,OU=HQ,DC=FR,DC=CONTOSO,DC=COM'
$str -replace '.+?,DC', ''

这会返回:

=COM

知道为什么即使使用非贪婪版本它也只得到最后一个? 我怎么能这样做?

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    只需拆分字符串:

    $parts = ('CN=John Doe,OU=IT,OU=Support,OU=Department,OU=HQ,DC=FR,DC=CONTOSO,DC=COM' -split ',')
    $newString = '{0}.{1}.{2}' -f $parts[-3].split('=')[1], $parts[-2].split('=')[1], $parts[-1].split('=')[1]
    

    【讨论】:

    • 我觉得应该有一个 AD 字符串类型可以让这更容易。
    • @TheIncorrigible1 听起来对你来说是一个很棒的项目 :)
    • 检查一下。这不是我第一次需要这样做,所以我告诉自己不要浪费时间
    【解决方案2】:

    好的,所以我采纳了@EBGreen 的建议并决定制作一个可以完成所有工作的函数:

    #Requires -Version 4
    Function ConvertFrom-DistinguishedName
    {
        [CmdletBinding()]
        [OutputType('System.Management.Automation.PSCustomObject')]
        Param(
            [Parameter(Position = 0, Mandatory)]
            [Alias('DistinguishedName', 'Name')]
            [ValidatePattern('^CN=.+?,(OU=.+?,)+DC=.+$')]
            [string]
            $Path
        )
        $local:ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
        $WS = $Path -split ',' # working set
    
        $User = $WS[0] -replace 'CN='
        $Domain = $WS.Where({$PSItem.StartsWith('DC=')}).ToLower() -replace 'dc=' -join '.'
        $OU = $WS.Where({$PSItem.StartsWith('OU=')}) -replace 'OU='
        [array]::Reverse($OU)
    
        [pscustomobject]@{
            'User'   = $User
            'Domain' = $Domain
            'OU'     = $OU -join '\'
        }
    }
    
    PS C:\> ConvertFrom-DistinguishedName 'CN=John Doe,OU=IT,OU=Support,OU=Department,OU=HQ,DC=FR,DC=CONTOSO,DC=COM'
    
    User     Domain         OU
    ----     ------         --
    John Doe fr.contoso.com HQ\Department\Support\IT
    

    最终结果?这会将您的可分辨 AD 名称转换为您可以轻松使用的 PSCustomObject。

    【讨论】:

      【解决方案3】:

      要使域脱离专有名称,您需要使用-Split。最后我们可以使用-join 插入'.' DC之间

      这会将您的域字符串存储到$domain

      $dn = "CN=John Doe,OU=IT,OU=Support,OU=Department,OU=HQ,DC=FR,DC=CONTOSO,DC=COM"
      $domain = $dn -Split "," | ? {$_ -like "DC=*"}
      $domain = $domain -join "." -replace ("DC=", "")
      
      Write-Host "Current Domain: " $domain
      

      【讨论】:

        【解决方案4】:

        您应该使用 ^ 从头开始​​。

        $str = 'CN=John Doe,OU=IT,OU=Support,OU=Department,OU=HQ,DC=FR,DC=CONTOSO,DC=COM'
        $str = $str -replace '^.+?,DC',''
        $str = $str -replace 'DC=',''
        $str -replace ',','.'
        

        【讨论】:

        • 您可以将其缩短为$str -replace "^.*?,DC=" -replace ",DC=", "."
        【解决方案5】:

        由于还没有人费心解释这种行为:

        替换操作替换每个字符串中出现的模式.+?,DC,因此它首先删除CN=John Doe,OU=IT,OU=Support,OU=Department,OU=HQ,DC,然后从替换停止的地方继续并删除=FR,DC,然后是@ 987654324@,只剩下=COM

        为避免这种行为,您需要将表达式锚定在字符串的开头 (^),正如其他人已经建议的那样。用点替换剩余的 ,DC= 的第二个替换可以菊花链式连接到第一个,因此您只需要一个语句:

        $str -replace '^.*?,dc=' -replace ',dc=', '.'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-21
          • 1970-01-01
          相关资源
          最近更新 更多