我正在尝试在 PowerShell 中提取路径的特定部分。
代码如下所示:
$Path -replace '/\/(main)?\/?$/gis',""
这里有几个例子和预期的输出:
示例 1:
$Path: "C://Users/admin/Documents/StackOverflow/"
预期输出:“C://Users/admin/Documents/StackOverflow”
实际输出:“C://Users/admin/Documents/StackOverflow/”
示例 2:
$Path: "C://Users/admin/Documents/StackOverflow/main"
预期输出:“C://Users/admin/Documents/StackOverflow”
实际输出:“C://Users/admin/Documents/StackOverflow/main”
示例 3:
$Path: "C://Users/admin/Documents/StackOverflow/main/"
预期输出:“C://Users/admin/Documents/StackOverflow”
实际输出:“C://Users/admin/Documents/StackOverflow/main/”
有人可以告诉我我做错了什么吗?
代码在 JavaScript 中运行良好,所以我想知道为什么它在 PowerShell 中不起作用。
我也尝试了以下模式但没有成功:
'/(main)?/?$'
'(?s)/main/?$'
.NET 中的模式语法是
(?<options>)<pattern>
,而不是/<pattern>/<options>
:
$Path -replace '(?s)/(main)?/?$'
对于其余选项:
g
是隐含的,i
由PowerShell自动注入
正如 Wiktor Stribiżew 在 评论 中指出的那样,
s
选项不会为您提供给定模式的任何内容,但为了完整性,我将其包括在内
使用或:
$inputs = @("C://Users/admin/Documents/StackOverflow/",
"C://Users/admin/Documents/StackOverflow/main",
"C://Users/admin/Documents/StackOverflow/main/");
foreach($input in $inputs)
{
$result = $input -replace '/(main)/?$|/$',""
Write-Host $result
}
我认为您需要删除最后一个字符“/”或严格从目录“/main/”开始的所有内容。同时类似“/maindir/”的目录应该不用考虑了吧?
测试这个条件:
(/main/.*?|/main|/)$
Mathias 的有用答案 很好地解释了PowerShell 语法 问题与您的方法。
但是,要获得所需的输出,您的正则表达式本身也需要调整:
'(/main)?/?$'
# Sample paths
$paths = @(
"C://Users/admin/Documents/StackOverflow/"
"C://Users/admin/Documents/StackOverflow/main"
"C://Users/admin/Documents/StackOverflow/main/"
)
$paths -replace '(/main)?/?$'
# Variant, if you need to deal with both "\" and "/" as path separators:
# $paths -replace '([/\\]main)?[/\\]?$'
有关正则表达式的解释以及使用它进行实验的能力,请参阅this regex101.com page,但简而言之:它匹配每个字符串的end (
$
) 中的以下任何内容:a /
,如果存在 (?
),前面有 /main
,如果存在,所以实际上 /
,/main
和 /main/
都是匹配的。
顺便说一句:为了将可选逻辑(
(…)
)应用于整个字符串?
,需要一个分组结构(main
)。 (…)
是一个 capturing 组,这在你的情况下不是必需的,因为你不需要参考它以后捕获的内容。(?:…)
:
$paths -replace '(?:/main)?/?$'
-replace
,意味着 ''
(空字符串),因此会导致 removal 匹配的内容。
如您所见,当给定 array 输入字符串时,
-replace
对每个元素 进行 运算,并返回结果数组。
为了处理单个 多行 字符串,您可以应用
(?m)
内联正则表达式选项,以便匹配 each line 上的模式,因为 $
然后不引用整个字符串的末尾,但到每一行的末尾:
$multiLineStringWithPaths -replace '(?m)(?:/main)?/?$'