【问题标题】:Split string with "-"用“-”分割字符串
【发布时间】:2021-10-12 03:04:41
【问题描述】:
System.Management.Automation.RemoteException
name: CLD:HYB_Z_BASIS_ADMIN_SUPER
description: Basis Administrator
readOnly: 
roleReferences:
- roleTemplateAppId: it!b2455
  roleTemplateName: AuthGroup_Administrator
  name: AuthGroup_Administrator
- roleTemplateAppId: it!b2455
  roleTemplateName: AuthGroup_BusinessExpert
  name: AuthGroup_BusinessExpert
OK

我有上面的字符串,每行由 CRLF 分隔。我正在尝试将以下信息提取并拆分为用“-”分隔的两行,这样我可以获得两行的数组,但我没有得到正确的结果。

我的代码是:

$Myarray = $string -split "-"

- roleTemplateAppId: it!b2455
  roleTemplateName: AuthGroup_Administrator
  name: AuthGroup_Administrator
- roleTemplateAppId: it!b2455
  roleTemplateName: AuthGroup_BusinessExpert
  name: AuthGroup_BusinessExpert

【问题讨论】:

    标签: powershell split


    【解决方案1】:

    使用System.Text.RegularExpressions.Regex.Matches() 方法从字符串中提取多个匹配项:

    $string = @'
    System.Management.Automation.RemoteException
    name: CLD:HYB_Z_BASIS_ADMIN_SUPER
    description: Basis Administrator
    readOnly: 
    roleReferences:
    - roleTemplateAppId: it!b2455
      roleTemplateName: AuthGroup_Administrator
      name: AuthGroup_Administrator
    - roleTemplateAppId: it!b2455
      roleTemplateName: AuthGroup_BusinessExpert
      name: AuthGroup_BusinessExpert
    OK
    '@
    
    # Find all matches for the given regex and return the matched
    # text (.Value) for each.
    # Returns 2 three-line strings.
    [regex]::Matches($string, '(?m)^- .+\n.+\n.+').Value
    

    注意:该解决方案依赖于一个单、多行字符串作为输入。如果您有一个 array 字符串,请先将它们与 [Environment]::NewLine 连接;例如$multilineString = 'foo', 'bar' -join [Environment]::NewLine;您还可以将此技术应用于从外部程序捕获的输出 - 请参阅this answer 的底部。

    有关正则表达式(?m)^- .+\n.+的详细解释以及试验能力,请参阅this regex101.com page

    注意:

    • 从 PowerShell 7.2 开始,-match、PowerShell 的 regular-expression matching operator 最多只能找到 一个 匹配项; 多个匹配需要使用 .NET API 会带来很大的复杂性; GitHub issue #7867 提议引入 -matchall 运营商来解决这个问题 - 虽然该提议已获批准,但尚未有人加紧实施。

    至于你尝试了什么

    -split "-":

    • 标记整个字符串,因此您将获得需要后过滤的无关信息
    • 从结果标记中排除-(因为它们充当分隔符),这使得过滤掉相关标记变得更加困难
    • 不将标记限制为仅前 2 行。

    使用-split 的解决方案,可能的,但需要额外使用-match,这使得解决方案更复杂且效率更低:

    # Same output as above.
    $string -split '(?m)(^- .+\n.+\n.+)' -match '^- '
    

    将正则表达式的相关部分包含在(...) 中,即使其成为捕获组,会导致-split 在返回的标记中包含该组的匹配项; -match '^- ' 然后过滤掉所有- 开头的标记,只留下2个感兴趣的两行字符串。

    【讨论】:

      猜你喜欢
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 2020-03-07
      • 1970-01-01
      • 2012-02-04
      相关资源
      最近更新 更多