Windows Powershell脚本用于在特定字符串后查找和替换字符串

问题描述 投票:1回答:2

我目前正在使用Powershell脚本将AS3类转换为JavaScript。

下面是需要转换的示例代码。

package somePackageName
{
     class someClassName
     {
           // other codes
     }
}

我需要删除整个包块,并且“class someClassName {”应该转换为“function someClassName(){”。

“someClassName”可以是任何字符串。

我需要像这样的输出。

 function someClassName()
 {

 }

这是我试过的。

 $l1 = Get-Content $dest | Where-Object {$_ -like 'class'} 
 $arr = $l1 -split ' '  
 $n1 = "function "+ $arr[1] + "() " +$arr[2] 
 (Get-Content $dest) -creplace $l1, $n1 | Set-Content $dest 

如果开口支撑与包装申报行在同一行,我能够实现我的意图。当Powershell逐行检查时,如果下一行中存在左括号,我就会被卡住。

windows powershell automation
2个回答
1
投票

基于正则表达式的解决方案

根据您是否愿意发布此处理或接受前导空格,您可以使用此正则表达式删除类外部的块并替换为函数声明。这比它需要的更麻烦但更安全,因为我们无法猜测// other codes是什么。你可以直接匹配整个类块,但是如果有其他花括号那么它会使正则表达式变得混乱。

PS M:\> (Get-Content -Raw $dest) -replace "(?sm).*?class (\w+)(.*)}",'function $1()$2'
function someClassName()
     {
           // other codes
     }

有关正则表达式正在做什么的更多详细信息,请参阅Regex101

基本上将所有内容转储到单词class(第一次)。然后保持一切,直到最后一个结束支架

请注意较大部分中的前导空格。这是对现有空间的尊重。为了解释这一点,我们需要计算缩进。简单地删除所有前导空格会破坏类/函数中的现有缩进。

所以这样的解决方案可能是首选:

# Read in the file as a single string
$raw = (Get-Content -Raw $dest)

# Using the line that has the class declaration measure the number of spaces in front of it. 
[void]($raw -match "(?m)^(\s+)class")
$leadingSpacesToRemove = $Matches[1].Length

# Remove the package block. Also remove a certain amount of leading space. 
$raw -replace "(?sm).*?class (\w+)(.*)}",'function $1()$2' -replace "(?m)^\s{$leadingSpacesToRemove}"

减少正则表达式

似乎过滤没有前导空格的线条是一种简单的方法,可以缩小到你想要的范围。

Get-Content $dest | Where-Object{$_.StartsWith(" ")}

从那里我们仍然需要更换“类”并处理领先的空间。对于那些我们将使用类似于上面所示的解决方案的人。

# Read in the file as a single string. Skipping the package wrapper since it has no leading spaces.
$classBlock = Get-Content $dest | Where-Object{$_.StartsWith(" ")} 

# Get the class name and the number of leading spaces. 
$classBlock[0] -match "^(\s+)class (\w+)" | Out-Null
$leadingSpacesToRemove = $matches[1].Length
$className = $matches[2]

# Output the new declaration and the trimmed block. 
# Using an array to start so that piping output will be in one pipe
@("function $className()") + ($classBlock | Select -Skip 1) -replace "^\s{$leadingSpacesToRemove}"

两种解决方案都试图考虑您的确切规格,并解释类块中存在奇怪的东西。


0
投票

我建议使用正则表达式:

                           #class myclass -> function myclass()
@(Get-Content $dest) -creplace 'class\s(.+)', 'function $1()' |
    Set-Content $dest

这将捕获类声明并将其替换为类名捕获的反向引用。

© www.soinside.com 2019 - 2024. All rights reserved.