需要将多个文本文件中的字符串替换为相同的字符串,但捕获组2替换为自身和捕获组4的总和。
字符串:Total amount $11.39 | Change $0.21
所需结果:Total amount $11.60 | Change $0.21
我尝试了几种方法。这是我的最后一次尝试,似乎没有错误,但对字符串没有任何更改。
$Originalfolder = "$ENV:userprofile\Documents\folder\"
$Originalfiles = Get-ChildItem -Path "$Originalfolder\*"
$RegexPattern = '\b(Total\s\amount\s\$)(\d?\d?\d?\d?\d\.?\d?\d?)(\s\|\sChange\s\$)(\d?\d?\d\.?\d?\d?)\b'
$Substitution = {
Param($Match)
$Result = $GP1 + $Sumtotal + $GP3 + $Change
$GP1 = $Match.Groups[1].Value
$Total = $Match.Groups[2].Value
$GP3 = $Match.Groups[3].Value
$Change = $Match.Groups[4].Value
$Sumtotal = ($Total + $Change)
return [string]$Result
}
foreach ($file in $Originalfiles) {
$Lines = Get-Content $file.FullName
$Lines | ForEach-Object {
[Regex]::Replace($_, $RegexPattern, $Substitution)
} | Set-Content $file.FullName
}
答案 0 :(得分:0)
这是我的操作方式:这是从较大的脚本中抽出的,该脚本会定期扫描目录中的文件,然后执行类似的操作,并且我已迅速将变量更改为混淆状态,因此请大声喊叫工作,明天我会详细介绍。
它也需要备份每个文件,并在重命名之前使用临时副本。
请注意,它还会发送电子邮件警报(末尾代码),以说明是否进行了任何处理-这是因为它旨在按原计划中的计划任务运行
$backupDir = "$pwd\backup"
$stringToReplace = "."
$newString = "."
$files = @(Get-ChildItem $directoryOfFiles)
$intFiles = $files.count
$tmpExt = ".tmpDataCorrection"
$DataCorrectionAppend = ".DataprocessBackup"
foreach ($file in $files) {
$content = Get-Content -Path ( $directoryOfFiles + $file )
# Check whether there are any instances of the string
If (!($content -match $stringToReplace)) {
# Do nothing if we didn't match
}
Else {
#Create another blank temporary file which the corrected file contents will be written to
$tmpFileName_DataCorrection = $file.Name + $tmpExt_DataCorrection
$tmpFile_DataCorrection = $directoryOfFiles + $tmpFileName_DataCorrection
New-Item -ItemType File -Path $tmpFile_DataCorrection
foreach ( $line in $content ) {
If ( $line.Contains("@")) {
Add-Content -Path $tmpFile_DataCorrection -Value $line.Replace($stringToReplace,$newString)
#Counter to know whether any processing was done or not
$processed++
}
Else {
Add-Content -Path $tmpFile_DataCorrection -Value $line
}
}
#Backup (rename) the original file, and rename the temp file to be the same name as the original
Rename-Item -Path $file.FullName -NewName ($file.FullName + $DataCorrectionAppend) -Force -Confirm:$false
Move-Item -Path ( $file.FullName + $DataCorrectionAppend ) -Destination backupDir -Force -Confirm:$false
Rename-Item -Path $tmpFile_DataCorrection -NewName $file.FullName -Force -Confirm:$false
# Check to see if anything was done, then populate a variable to use in final email alert if there was
If (!$processed) {
#no message as did nothing
}
Else {
New-Variable -Name ( "processed" + $file.Name) -Value $strProcessed
}
} # Out of If loop
}
答案 1 :(得分:0)
一方面,您的正则表达式甚至与您要替换的正则表达式都不匹配,因为您在a
中逃脱了amount
:
\b(Total\s\amount\s\$)(\d?\d?\d?...
# ^^
\a
是与{alarm”或“ bell”字符\u0007
匹配的escape sequence。
此外,如果要计算两个捕获的总和,则需要先将它们转换为数值,否则+
运算符只会将两个字符串连接起来。
$Total = $Match.Groups[2].Value
$Change = $Match.Groups[4].Value
$Sumtotal = $Total + $Change # gives 11.390.21
$Sumtotal = [double]$Total + [double]$Change # gives 11.6
您需要在定义其他变量之后构建$Result
,否则替换函数将只返回一个空字符串。
更改此:
$RegexPattern = '\b(Total\s\amount\s\$)(\d?\d?\d?\d?\d\.?\d?\d?)(\s\|\sChange\s\$)(\d?\d?\d\.?\d?\d?)\b'
$Substitution = {
param ($Match)
$Result = $GP1 + $Sumtotal + $GP3 + $Change
$GP1 = $Match.Groups[1].Value
$Total = $Match.Groups[2].Value
$GP3 = $Match.Groups[3].Value
$Change = $Match.Groups[4].Value
$Sumtotal = ($Total + $Change)
return [string]$Result
}
对此:
$RegexPattern = '\b(Total\samount\s\$)(\d?\d?\d?\d?\d\.?\d?\d?)(\s\|\sChange\s\$)(\d?\d?\d\.?\d?\d?)\b'
$Substitution = {
Param($Match)
$GP1 = $Match.Groups[1].Value
$Total = [double]$Match.Groups[2].Value
$GP3 = $Match.Groups[3].Value
$Change = [double]$Match.Groups[4].Value
$Sumtotal = ($Total + $Change)
$Result = $GP1 + $Sumtotal + $GP3 + $Change
return [string]$Result
}
和代码将主要执行您想要的操作。 “最多”,因为它不会将计算出的数字格式化为两位小数。您需要自己做。使用format operator(-f
)并将替换功能更改为以下形式:
$Substitution = {
Param($Match)
$GP1 = $Match.Groups[1].Value
$Total = [double]$Match.Groups[2].Value
$GP3 = $Match.Groups[3].Value
$Change = [double]$Match.Groups[4].Value
$Sumtotal = $Total + $Change
return ('{0}{1:n2}{2}{3:n2}' -f $GP1, $Sumtotal, $GP3, $Change)
}
作为旁注:子表达式\d?\d?\d?\d?\d\.?\d?\d?
可以缩短为\d+(?:\.\d+)?
(一个或多个数字,可以选择后面跟一个句点和一个或多个数字),或更确切地说,可以缩短为{ {1}}(一到四位数字,可以选择后面跟一个句点,最多两位数)。