在PowerShell中替换两个字符串之间的多个字符串中的特殊字符

时间:2014-07-23 11:39:23

标签: string powershell character-replacement

背景:我将.mp4视频的文件名更改为小写,并替换了特殊字符和空格。现在我必须以类似的方式更改.txt文件中的关联URL。有许多文本文件包含大量涉及视频的URL。

问题:我应该在任何文本文件中替换“flashplayer”和“/ flashplayer”之间的每个字符串中的特殊字符,但不得更改flashplayer标记之外的任何内容。

我不知道如何选择“flashplayer”和“/ flashplayer”之间的字符串进行替换。

示例字符串:

(flashplayer width="640" height="480" position="1")file=/wiki/data/media/sales/a/ö 2.mp4&config=/wiki/lib/plugins/flashplayer/config_video.xml&start=0(/flashplayer)

此示例包含在文本文件(DokuWiki页面)中。 ()暗示标记字符。

示例输出字符串:

(flashplayer width="640" height="480" position="1")file=/wiki/data/media/sales/a/oe_2.mp4&config=/wiki/lib/plugins/flashplayer/config_video.xml&start=0(/flashplayer)

使用rename-item替换应该是:

  • ä= ae
  • ö= oe
  • ü= ue
  • ''='_'

更新: 脚本看起来像:

# vars (User-Eingabe)
$source = "d:\here\name\test\pages"
$search = '(\<flashplayer.*?\>file\=/wiki/87sj38d/media)(.*?)(\<\/flashplayer\>)'
$a = 1
Write-Host "`nSource:`t $source`n"
# replace special characters
gci $source -r -Filter *.txt | ForEach-Object {
    $text = Get-Content $_.FullName | ForEach-Object {
        if($_ -match $search) {
            $_ -replace [Regex]::Escape($Matches[2]), ($Matches[2] -replace'ö', 'oe' -replace'ä', 'ae' -replace'ü', 'ue' -replace'\s', '_' )
            $output = $Matches[2]
            $tags = $a++         
            Write-Host "`nTag $tags : $output"
        } else {
            $_
        }
    }
    $text | Set-Content $_.FullName
}

文本文件包含一行代码:

{{backlinks>path:product:description:kennwort_aendern}}

只有删除这行代码,脚本才有效。否则flashplayertags之间的字符串保持不变。令人困惑的是,更换操作有时,有时不操作。 flashplayertags之间的字符串可以包含许多特殊字符。请参阅示例字符串:

<flashplayer_width="640"_height="480"_position="1">file=/wiki/87sj38d/media/ab/any/test/1001_Grundlagen Kennwort ändern.mp4&image=/wiki/87sj38d/media/ab/any/test/1001_Grundlagen Kennwort ändern.jpg&config=/wiki/lib/plugins/flashplayer/config_video.xml&start=0</flashplayer>

Write-Host $输出正确显示所有字符串,但替换功能无法正常运行。

2 个答案:

答案 0 :(得分:2)

你可以尝试这样的事情。对于每个文本文件,它将替换每个flashplayer行上的特殊字符。

Get-ChildItem -Path "c:\FolderOfTextfiles" -Filter *.txt | ForEach-Object {

    $text = Get-Content $_.FullName | ForEach-Object {
        if($_ -match '(?<=\(flashplayer.*?\))(.*?)(?=\(/flashplayer\))') {
            $_ -replace [Regex]::Escape($Matches[1]), ($Matches[1] -replace'ö', 'oe' -replace 'ä', 'ae' -replace 'ü', 'ue' -replace '\s', '_' )
        } else {
            $_
        }
    }

    $text | Set-Content $_.FullName

}

更新:如果文本包含换行符,那么您可以尝试使用此全局多行正则表达式匹配apporach:

$s = @'
<flashplayer_width="640"_height="480"_position="1">file=/wiki/87sj38d/media/ab/any/test/1001_Grundlagen Kennwort ändern.mp4&image=/wiki/87sj38d/media/ab/
any/test/1001_Grundlagen Kennwort ändern.jpg&config=/wiki/lib/plugins/flashplayer/config_video.xml&start=0</flashplayer>
<flashplayer_width="640"_height="480"_position="1">file=/wiki/87sj38f/media/ab/any/test/1001_Grundlagen Kennwort ändern.mp4&image=/wiki/87sj38d/media/ab/any/test/1001_Grundlagen Kennwort ändern.jpg&
config=/wiki/lib/plugins/flashplayer/config_video.xml&start=0</flashplayer>
'@

#Read text as single string
#PS 3.0+
#$s = Get-Content .\test.txt -Raw

#PS 2.0
#$s = Get-Content .\test.txt | Out-String

$s = [regex]::Replace($s, '(?s)(?<=<flashplayer.*?>file=/wiki/87sj38d/media).*?(?=</flashplayer>)', { 
    param([System.Text.RegularExpressions.Match]$m)
    $m.Value -replace 'ö', 'oe' -replace 'ä', 'ae' -replace 'ü', 'ue' -replace ' ', '_'
})

$s    

#Save
#$s | Set-Content .\test.txt

这是一个更复杂的解决方案,因为AFAIK在当前的PowerShell版本中使用$1时无法修改-replace 'pattern', '$1'(捕获的组)。如果有人有更好的解决方案,请分享:)

答案 1 :(得分:0)

您可以使用以下命令替换上述字符。您需要根据文本文件的位置更改文件路径。使用Replace-FileString.ps1; http://windowsitpro.com/scripting/replacing-strings-files-using-powershell

./Replace-FileString  -Pattern '(flashplayer)(.*)ä(.*)(\/flashplayer)'  -Replacement '$1$2ae$3$4'  -Path C:\test\*.txt  -Overwrite
./Replace-FileString  -Pattern '(flashplayer)(.*)ö(.*)(\/flashplayer)'  -Replacement '$1$2oe$3$4'  -Path C:\test\*.txt  -Overwrite
./Replace-FileString  -Pattern '(flashplayer)(.*)ü(.*)(\/flashplayer)'  -Replacement '$1$2ue$3$4'  -Path C:\test\*.txt  -Overwrite
./Replace-FileString  -Pattern '(flashplayer)(.*) (.*)(\/flashplayer)'  -Replacement '$1$2_$3$4'  -Path C:\test\*.txt  -Overwrite

它打开并写入所有文本文件(即使它没有改变任何东西)。它只会更改字符串“flashplayer”和“/ flashplayer”之间的“ä”,“ö”,“ü”或“”的行。

相关问题