我想预处理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
,这是正确的。
有人可以告诉我为什么会这样吗?非常感谢你!
答案 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
运算符进行替换,而不是从头开始构建整行。但是,因为它再次评估正则表达式,它可能导致大型输入文件的性能问题。