2013-10-03 2 views
0

У меня есть следующий сценарий powershell, выполняющийся над классом C#, чтобы заменить конструктор на пустой конструктор. Я делаю это по нескольким файлам, которые были автогенерированы.Как заменить текст внутри фигурных скобок, используя Powershell?

$nl = [Environment]::NewLine 
foreach($item in Get-ChildItem $path) {    
     if($item.extension -eq ".cs") { 

      $name = $item.name 
      $name = $name.replace('.cs', '') 
      $reg = '(public ' + $name + '\(.*?\})' 
      $constructorString = [regex]$reg 
      $emptyConstructor = 'public ' + $name + '()' + $nl + '{' + $nl + '}' + $nl 


      Get-Content $item.fullname -Raw | Where-Object { $_ -match $constructorString } | ForEach-Object { $_ -replace $constructorString, '$1'}    
     } 
} 

Классы имеют форму

public Bar() 
{ 
    this.foo = new Foo(); 
} 

Это приводит не спички, дайте мне знать, если требуется дополнительная информация.

+0

Вы можете просто совпадение с 'this.foo = new Foo();' или '" this. $ Name.ToLower() = new $ name() "' и заменить его пустой строкой? – rae1

ответ

2

Нет необходимости преобразовывать шаблон в регулярное выражение. Попробуйте это:

$item | Get-Content -raw | Where {$_ -match "(?s)(public\s+${name}\s*\(.*?\})"} | ... 

Я считаю, что этот вопрос вы работаете в том, что хотя вы читали C# файл в виде одной строки с помощью параметра -Raw, есть разрывы строк в строке, .* не будет пересекать если вы не используете однолинейный режим в регулярном выражении. Это то, что делает (?s).

Кроме того, если вы на PowerShell V3 можно использовать базовое вместо замены например .:

$name = $item.basename 

BTW вы смотрели на Roslyn в качестве альтернативы для поиска регулярных выражений/заменить подход? Roslyn построит для вас AST для каждого исходного файла. С этим вы можете легко найти конструкторы по умолчанию и заменить его на пустой конструктор.

Смежные вопросы