【问题标题】:Powershell regex group regex matches but doesn't have my group. What's missing?Powershell 正则表达式组正则表达式匹配但没有我的组。少了什么东西?
【发布时间】:2020-02-17 22:57:33
【问题描述】:

我有一些从 jenkins 脚本移植的代码,我需要它作为 shell 命令。所以我知道正则表达式 有效 - 让我大吃一惊的是它如何 ma​​tch 但没有我的捕获组。我需要的只是根级目录名称:

foo
baz

它如何“匹配”但没有我的组?顺便说一句:如果有更简单的方法来实现这一点,我会全力以赴。

PS E:\SysData\Jenkins\workspace\chb0_chb0mb_example> git diff --name-only origin/master  feature/foo |  %{ Resolve-Path -Relative $_ } | sls  '.\\.*\\.*'  | sls '\\.\\(.+?)\\.*|.*' | %{$_.matches}


Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 48
Value    : .\foo\Nuget\deleteme.txt

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 55
Value    : .\baz\QC_OH_DARKESol\deleteme.txt

【问题讨论】:

  • git 输出什么?
  • .gitignore Jenkinsfile foo\Nuget\deleteme.txt bar\QC_OH_DARKESol\deleteme.txt
  • 顺便说一句:您可以将git --diff 输出直接 传送到Resolve-Path - 不需要% (ForEach-Object),这会不必要地减慢速度:git diff --name-only origin/master feature/foo | Resolve-Path -Relative

标签: regex git powershell


【解决方案1】:

假设我的问题是对的。一方面,一个字面句号必须被反斜杠。但无论如何它都可以在没有反斜杠的情况下工作。开头没有反斜杠。不是每个人都有 git 命令。这种模式可能更短,但它有效。我正在扩展您没有显示的 groups 属性。

'.\foo\Nuget\deleteme.txt' | sls '.\\(.+?)\\.*|.*' | % matches | % groups

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 6
Value    : .\foo\

Success  : True
Name     : 1
Captures : {1}
Index    : 2
Length   : 3
Value    : foo

object 从第一个 sls 传递到第二个 sls 会导致组捕获出现问题。这似乎是一个错误。已提交:piping select-string to itself and the strange effect on matches value 属性甚至不在此处。

'abc' | select-string a | select-string '(b)' | % matches | % groups

Groups   : {0}
Success  : True
Name     : 0
Captures : {0}
Index    : 0
Length   : 1
Value    : a   # should be b

与将纯字符串发送到第二个选择字符串相比,它会给出正确的输出:

'abc' | select-string a | % line | select-string '(b)' | % matches | % groups

Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 1
Length   : 1
Value    : b

Success  : True
Name     : 1
Captures : {1}
Index    : 1
Length   : 1
Value    : b

【讨论】:

    【解决方案2】:

    js2010's helpful answer 指出了你的方法的一个潜在问题(.\\ 应该是\.\\),简洁地展示了你所经历的无法解释的行为(他们为此创建了一个GitHub issue),并建议了一个解决方法(插入| % Line)。

    更直接地解决您的问题:

    # Inputs are sample paths.
    '.\foo\Nuget\deleteme.txt',
    '.\bar\QC_OH_DARKESol\deleteme.txt' | 
      foreach { if ($_ -match '^\.\\([^\\]+)') { $Matches[1] } }
    

    以上产生以下字符串:

    foo
    bar
    

    也就是说,它从输入路径中提取文字 .\ 之后的第一个路径组件,使用 foreach (ForEach-Object) 将 -matchregular-expression matching operator 应用于每个输入字符串,其匹配结果反映在自动$Matches 变量中,这是一个哈希表,其0 条目是整体匹配,其中条目1 包含第一个捕获组的值, 2第二个,...; 已命名捕获组(例如,(?<root>...)),如果存在,则具有按其名称命名的条目(例如,root)。


    另一种方法是将switch statement-Regex 选项一起使用:

    switch -Regex (
      git diff --name-only origin/master feature/foo | Resolve-Path -Relative
    ) {
      '^\.\\([^\\]+)' { $Matches[1] } 
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      相关资源
      最近更新 更多