I have text files that contain 2 numbers separated by a '+' sign. Trying to figure out how to replace them with currency equivalent .
Example Strings:
20+2 would be converted to $0.20+$0.02 USD
1379+121 would be> $13.79+$1.21 USD
400+20 would be $4.00+$0.20 USD
and so on.
I have tried using a few angles but they do not work or provide odd results. I tried to do it here by attempting to find by all patterns I think would come up .
.\Replace-FileString.ps1 "100+10" '$1.00+$0.10' $path1\*.txt -Overwrite
.\Replace-FileString.ps1 "1000+100" '$10.00+$1.00' $path1\*.txt -Overwrite
.\Replace-FileString.ps1 "300+30" '$3.00+$0.30' $path1\*.txt -Overwrite
.\Replace-FileString.ps1 "400+20" '$4.00+$0.20' $path1\*.txt -Overwrite
or this which just doesn't work.
Select-String -Path .\*txt -Pattern '[0-9][0-9]?[0-9]?[0-9]?[0-9]?\+[0-9][0-9]?[0-9]?[0-9]?[0-9]?' | ForEach-Object {$_ -replace ", ", $"} {$_ -replace "+", "+$"}
I tried to do it here by attempting to find by all patterns I think would come up
Don't try this - we're humans, and we won't think of all edge cases and even if we did, the amount of code we needed to write (or generate) would be ridiculous.
We need a more general solution here, and regex might indeed be helpful with this.
The pattern you describe could be expressed as three distinct parts:
+
)With this in mind, let's start to simplifying the regex pattern to use:
\b\d+\+\d+\b
or, written out with explanations:
\b # a word boundary
\d+ # 1 or more digits
\+ # 1 literal plus sign
\d+ # 1 or more digits
\b # a word boundary
Now, in order to transform an absolute value of cents into dollars, we'll need to capture the digits on either side of the +
, so let's add capture groups:
\b(\d+)\+(\d+)\b
Now, in order to do anything interesting with the captured groups, we can utilize the Regex.Replace()
method - it can take a scriptblock as its substitution argument:
$InputString = '1000+10'
$RegexPattern = '\b(\d+)\+(\d+)\b'
$Substitution = {
param($Match)
$Results = foreach($Amount in $Match.Groups[1,2].Value){
$Dollars = [Math]::Floor(($Amount / 100))
$Cents = $Amount % 100
'${0:0}.{1:00}' -f $Dollars,$Cents
}
return $Results -join '+'
}
In the scriptblock above, we expect the two capture groups ($Match.Groups[1,2]
), calculate the amount of dollars and cents, and then finally use the -f
string format operator to make sure that the cents value is always two digits wide.
To do the substitution, invoke the Replace()
method:
[regex]::Replace($InputString,$RegexPattern,$Substitution)
And there you go!
Applying to to a bunch of files is as easy as:
$RegexPattern = '\b(\d+)\+(\d+)\b'
$Substitution = {
param($Match)
$Results = foreach($Amount in $Match.Groups[1,2].Value){
$Dollars = [Math]::Floor(($Amount / 100))
$Cents = $Amount % 100
'${0:0}.{1:00}' -f $Dollars,$Cents
}
return $Results -join '+'
}
foreach($file in Get-ChildItem $path *.txt){
$Lines = Get-Content $file.FullName
$Lines |ForEach-Object {
[regex]::Replace($_, $RegexPattern, $Substitution)
} |Set-Content $file.FullName
}