Powershell:拆分路径不能在-Replace中工作

时间:2015-12-01 00:55:42

标签: regex powershell

我想预处理C代码,替换 #include "../../abc/efg/hij.h" "hij.h"

我使用命令

'#include "../../abc/efg/hij.h"' -replace '(#include\s+)(".*\w+\.h")',"$(Split-Path -Leaf `$2)"

进行更换。但是,无论我如何尝试(使用单引号/双引号,$()和其他方法),最后的字符串(我还没有Set-Content),只想在标准输出中看到结果)仍然是"../../abc/efg/hij.h"

当我运行Split-Path -Leaf "../../abc/efg/hij.h"时,结果为hij.h,这是正确的。

有人可以告诉我为什么会这样吗?非常感谢你!

2 个答案:

答案 0 :(得分:4)

使用正则表达式进行路径解析似乎很奇怪,但是后来尝试使用Split-Path来执行它。为什么不完全用正则表达式替换?

通过捕捉它并将其替换为任何东西来摆脱你不想要的位:

PS C:\> '#include "../../abc/efg/hij.h"' -replace '(?<=#include\s+")(.*/)(?=\w+\.h")'
#include "hij.h"

或者通过捕获并将其放入新行来保留您想要的位:

PS C:\> '#include "../../abc/efg/hij.h"' -replace '#include\s+".*/(.*\.h)"','#include "$1"'
#include "hij.h"

答案 1 :(得分:2)

您遇到的问题是-replace运算符与正则表达式匹配并以原子方式执行替换。它没有提供在两个操作之间运行任何PowerShell代码的方法。

在代码中,脚本块(Split-Path -Leaf $2)在匹配正则表达式之前首先进行评估。然后将该脚本块($null,空字符串或异常(取决于变量$2保存的值)的结果传递给-replace,并观察结果。

您想要的是能够在匹配正则表达式并替换它之间运行PowerShell命令。一种方法是使用-match匹配正则表达式,然后使用$matches变量中的匹配来构建替换字符串。

$oldLine -match '#include\s+"(.*\w+\.h)"'
$newLine = '#include "{0}"' -f (split-path -leaf $matches[1])

您可以选择使用-replace运算符进行替换,而不是从头开始构建整行。但是,因为它再次评估正则表达式,它可能导致大型输入文件的性能问题。