Remove all whitespace, except between quotes - powershell

I have been trying to find a way to remove white space from a specific place in a string but have yet to have any luck. I cant just use -Replace to get rid of all white spaces. Ideally I would like to define that everything outside of double quotes gets removed.
I am starting with a string like:
{ [ "Data: I have some data here", "%somedata% == 1234" ] }
And I want it to end up like:
{["Data: I have some data here","%somedata% == 1234"]}
Any ideas on how I can accomplish this?

putting your string into $InStuff, this will replace any 2-or-more spaces with nothing. note that the -replace operator uses regex, while the .Replace() method does not.
$InStuff -replace ' {2,}', ''
output ...
["Data: I have some data here","%somedata% == 1234"]}

Related

Switch statement with RegEx - having trouble getting a switch statement not to match if string has a dot

Lets say I have switch statement like so:
$NewName = "test.psd"
switch -RegEX ($NewName) {
"^\..*" { #if string starts with "." it means only change extension
'Entry Starts with a "."'
}
".*\..*" { # "." is in the middle , change both basename and extension
'Entry does not start with a "."'
}
"[^.]" { # if no "." at all, it means only change base name
'No "." present'
}
}
The first and second condidtions work as expected, but the last one always triggers. It will trigger against:
$NewName = "test.psd"
$NewName = ".psd"
$NewName = "test"
Doesnt regex "[^.]" mean if there is a dot, dont match. Essentially only trigger in the absence of a dot.
My expected outcome is for the last statement to only trigger if there is not dot present.
Any help on this, would be wellcome.
That would only work if "." were the only character. All the other characters would match it. You would have to repeat that pattern for every character on the line. See also Regex - Does not contain certain Characters
'a.' -match '^[^.]+$'
False
'ab' -match '^[^.]+$'
True
The dot is a special character in regular expressions, and needs to be escaped when you want to use a literal dot. Try "[^\.]" for the regular expression in the third case.

Powershell - Remove text and capitalise some letters

Been scratching my head on this one...
I'd like to remove .com and capitalize S and T from: "sometext.com"
So output would be Some Text
Thank you in advance
For most of this you can use the replace() member of the String object.
The syntax is:
$string = $string.replace('what you want replaced', 'what you will replace it with')
Replace can be used to erase things by using blank quotes '' for the second argument. That's how you can get rid of .com
$string = $string.replace('.com','')
It can also be used to insert things. You can insert a space between some and text like this:
$string = $string.replace('et', 'e t')
Note that using replace does NOT change the original variable. The command below will print "that" to your screen, but the value of $string will still be "this"
$string = 'this'
$string.replace('this', 'that')
You have to set the variable to the new value with =
$string = "this"
$string = $string.replace("this", "that")
This command will change the value of $string to that.
The tricky part here comes in changing the first t to capital T without changing the last t. With strings, replace() replaces every instance of the text.
$string = "text"
$string = $string.replace('t', 'T')
This will set $string to TexT. To get around this, you can use Regex. Regex is a complex topic. Here just know that Regex objects look like strings, but their replace method works a little differently. You can add a number as a third argument to specify how many items to replace
$string = "aaaaaa"
[Regex]$reggie = 'a'
$string = $reggie.replace($string,'a',3)
This code sets $string to AAAaaa.
So here's the final code to change sometext.com to Some Text.
$string = 'sometext.com'
#Use replace() to remove text.
$string = $string.Replace('.com','')
#Use replace() to change text
$string = $string.Replace('s','S')
#Use replace() to insert text.
$string = $string.Replace('et', 'e t')
#Use a Regex object to replace the first instance of a string.
[regex]$pattern = 't'
$string = $pattern.Replace($string, 'T', 1)
What you're trying to achieve isn't well-defined, but here's a concise PowerShell Core solution:
PsCore> 'sometext.com' -replace '\.com$' -replace '^s|t(?!$)', { $_.Value.ToUpper() }
SomeText
-replace '\.com$' removes a literal trailing .com from your input string.
-replace '^s|t(?!$), { ... } matches an s char. at the start (^), and a t that is not (!) at the end ($); (?!...) is a so-called negative look-ahead assertion that looks ahead in the input string without including what it finds in the overall match.
Script block { $_.Value.ToUpper() } is called for each match, and converts the match to uppercase.
-replace (a.k.a -ireplace) is case-INsensitive by default; use -creplace for case-SENSITIVE replacements.
For more information about PowerShell's -replace operator see this answer.
Passing a script block ({ ... }) to dynamically determine the replacement string isn't supported in Windows PowerShell, so a Windows PowerShell solution requires direct use of the .NET [regex] class:
WinPs> [regex]::Replace('sometext.com' -replace '\.com$', '^s|t(?!$)', { param($m) $m.Value.ToUpper() })
SomeText

Cut out first pattern in string

I'm trying to remove the first value from a string...
$string = "`"JSteward`",`"43518790`",`"512`",`"JSteward#mystuff.com`""
$fixedString = $string -replace "^`"[*]`",", ""
Write-Host $fixedString
The output results in:
"JSteward","43518790","512","JSteward#mystuff.com"
The output I want:
"43518790","512","JSteward#mystuff.com"
can anyone tell me what's wrong with my regex?
Modified to match correct solution that this helped solve, to keep the answer clean.
$fixedString = $string -replace '^"[^"]*",', ""
Basically it reads like this. From the beginning of the string, match double quotes and then match anything that is not double quotes, then match double quotes and a comma.

find and replace special characters powershell

I have a method that has an if statement that catches if it finds a special character. What I want to do now if find the position of the special characters and replace it with _A
Some Examples
test# becomes test_A
I#hope#someone#knows#the#answer# becomes I_Ahope_Asomeone_Aknows_Athe_Aanswer_A
or if it has more than one special character
You?didnt#understand{my?Question# becomes You_Adidnt_Aunderstand_Amy_AQuestion_A
Would I have to loop through the whole string and when I reach that character change it to _A or is there a quicker way of doing this?
# is just a character like any other, you can use the -replace operator:
PS C:\>'I#hope#someone#knows#the#answer#' -replace '#','_A'
I_Ahope_Asomeone_Aknows_Athe_Aanswer_A
Regex is magic, you can define all the special cases you like (braces will have to be escaped):
PS C:\>'You?didnt#understand{my?Question#' -replace '[#?\{]','_A'
You_Adidnt_Aunderstand_Amy_AQuestion_A
So your function could look something like this:
function Replace-SpecialChars {
param($InputString)
$SpecialChars = '[#?\{\[\(\)\]\}]'
$Replacement = '_A'
$InputString -replace $SpecialChars,$Replacement
}
Replace-SpecialChars -InputString 'You?didnt#write{a]very[good?Question#'
If you are unsure of which characters to escape, have the regex class do it for you!
function Replace-SpecialChars {
param(
[string]$InputString,
[string]$Replacement = "_A",
[string]$SpecialChars = "#?()[]{}"
)
$rePattern = ($SpecialChars.ToCharArray() |ForEach-Object { [regex]::Escape($_) }) -join "|"
$InputString -replace $rePattern,$Replacement
}
Alternatively, you can use the .NET string method Replace():
'You?didnt#understand{my?Question#'.Replace('#','_A').Replace('?','_A').Replace('{','_A')
But I feel the regex way is more concise

$macro substitution - ExpandString limitations

I am trying to implement macro replacement based on this discussion. Basically it works, but seems the ExpandString have some limitatoins:
main.ps1:
$foo = 'foo'
$text = [IO.File]::ReadAllText('in.config')
$ExecutionContext.InvokeCommand.ExpandString($text) | out-file 'out.config'
in.config (OK):
$foo
in.config (Error: "Encountered end of line while processing a string token."):
"
in.config (Error: "Missing ' at end of string."):
'
The documentation states:
Return Value: The expanded string
with all the variable and expression
substitutions done.
What is 'expression substitution' (may be this is my case)?
Is there some workaround?
The error is occurring because quotes (single and double) are special characters to the PowerShell runtime. They indicate a string and if they are to be used as just that character, they need to be escaped.
A possible workaround would be to escape quotes with a backtick, depending on your desired result.
For example if my text file had
'$foo'
The resulting expansion of that string would be
PS>$text = [io.file]::ReadAllText('test.config')
PS>$ExecutionContext.InvokeCommand.ExpandString($text)
$foo
If you wanted to have that variable expanded, you would need to escape those quotes.
`'$foo`'
PS>$text = [io.file]::ReadAllText('test.config')
PS>$ExecutionContext.InvokeCommand.ExpandString($text)
'foo'
or if you were going to have an unpaired single or double quote, you would need to escape it.
You could do a -replace on the string to escape those characters, but you'll have to make sure that is the desired effect across the board.
PS>$single, $double = "'", '"'
PS>$text = [io.file]::ReadAllText('test.config') -replace "($single|$double)", '`$1'
PS>$ExecutionContext.InvokeCommand.ExpandString($text)
NOTE: After you do the ExpandString call, you won't have the backticks hanging around anymore.