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

时间:2017-12-15 13:36:47

标签: windows powershell automation

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

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

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

我需要删除整个软件包块,并且" class someClassName {"应转换为"函数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逐行检查时,如果下一行中有左括号,我就会被卡住。

2 个答案:

答案 0 :(得分: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}"

两种解决方案都会尝试考虑您的确切规格,并说明类块中是否存在奇怪的内容。

答案 1 :(得分:0)

我建议使用正则表达式:

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

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