Strip all non letters and numbers from a string in Powershell? - powershell

I have a variable that has a string which recieves strange characters like hearts.
Besides that point, I wanted to know anyhow: How do I leave a string with only letters and numbers, discarding the rest or replacing it with nothing (not adding a space or anything)
My first thought was using a regular expression but I wanted to know if Powershell had something more native that does it automatically.

Let say you have variable like this:
$temp = '^gdf35#&fhd^^h%(#$!%sdgjhsvkushdv'
you can use the -replace method to replace only the Non-word characters like this:
$temp -replace "\W"
The result will be:
gdf35fhdhsdgjhsvkushdv

Consider white-listing approved characters, and replace anything that isn't whitelisted:
$temp = 'This-Is-Example!"£$%^&*.Number(1)'
$temp -replace "[^a-zA-Z0-9]"
ThisIsExampleNumber1
This gives added flexibility if you ever do want to include non-alphanumeric characters which may be expected as part of the string (e.g. dot, dash, space).
$temp = 'This-is-example!"£$%^&*.Number(2)'
$temp -replace "[^a-zA-Z0-9.-]"
This-is-example.Number2

Related

Powershell replace command not removing newline

I have text that prints out like this:
mdbAppText_Arr: [0]: The cover is open. {goes to next line here}
Please close the cover. and [1] Backprinter cover open
46
I tried getting rid of the newline after open., and it's still there. Any idea of a better way or fix for what I'm doing? I need to get rid of the newline because it's going to a csv file, and messing up formatting (going to newline there).
This is my code:
$mdbAppText_Arr = $mdbAppText.Split("|")
$mdbAppText_Arr[0].replace("`r",";").replace("`n",";").replace("`t",";").replace("&",";")
#replace newline/carriage return/tab with semicolon
if($alarmIdDef -eq "12-7")
{
Write-Host "mdbAppText_Arr: [0]: $($mdbAppText_Arr[0]) and [1] $($mdbAppText_Arr[1]) "
[byte] $mdbAppText_Arr[0][31]
}
I've been looking at:
replace
replace - this one has a link reference to lookup in the asci table, but it's unclear to me what column the byte equivalent is in the table/link.
I'm using PowerShell 5.1.
-replace is a regex operator, so you need to supply a valid regular expression pattern as the right-hand side operand.
You can replace most newline sequences with a pattern describing a substring consisting of:
an optional carriage return (\r? in regex), followed by
a (non-optional) newline character (\n in regex):
$mdbAppText_Arr = $mdbAppText_Arr -replace '\r?\n'

Swap string order in one line or swap lines order in powershell

I need to swap place of 2 or more regex strings in one line or some lines in a txt file in powershell.
In npp i just find ^(String 1.*)\r\n(String 2.*)\r\n(String 3.*)$ and replace with \3\r\n\1\r\n\2:
String 1 aksdfh435##%$dsf
String 2 aksddfgdfg$dsf
String 3 aksddfl;gksf
Turns to:
String 3 aksddfl;gksf
String 1 aksdfh435##%$dsf
String 2 aksddfgdfg$dsf
So how can I do it in Powershell? And if possible can I use the command by calling powershell -command in cmd?
It's basically exactly the same in PowerShell, eg:
$Content = #'
Unrelated data 1
Unrelated data 2
aksdfh435##%$dsf
aksddfgdfg$dsf
aksddfl;gksf
Unrelated data 3
'#
$LB = [System.Environment]::NewLine
$String1= [regex]::Escape('aksdfh435##%$dsf')
$String2= [regex]::Escape('aksddfgdfg$dsf')
$String3= [regex]::Escape('aksddfl;gksf')
$RegexMatch = "($String1.*)$LB($String2.*)$LB($String3.*)$LB"
$Content -replace $RegexMatch,"`$3$LB`$1$LB`$2$LB"
outputs:
Unrelated data 1
Unrelated data 2
aksddfl;gksf
aksdfh435##%$dsf
aksddfgdfg$dsf
Unrelated data 3
I used [System.Environment]::NewLine since it uses the default line break no matter what system you're on. Bound to a variable for easier to read code. Either
\r\n
or
`r`n
would've worked as well. The former if using single quotes and the latter (using backticks) when using double quotes. The backtick is what I use to escape $1, $2 and so on as well, that being the format to use when grabbing the first, second, third group from the regex.
I also use the [regex]::Escape('STRING') method to escape the strings to avoid special characters messing things up.
To use file input instead replace $Content with something like this:
$Content = Get-Content -Path 'C:\script\lab\Tests\testfile.txt' -Raw
and replace the last line with something like:
$Content -replace $RegexMatch,"`$3$LB`$1$LB`$2$LB" | Set-Content -Path 'C:\script\lab\Tests\testfile.txt'
In PowerShell it is not very different.
The replacement string needs to be inside double-qoutes (") here because of the newline characters and because of that, you need to backtick-escape the backreference variables $1, $2 and $3:
$str -replace '^(String 1.*)\r?\n(String 2.*)\r?\n(String 3.*)$', "`$3`r`n`$1`r`n`$2"
This is assuming your $str is a single multiline string as the question implies.

Can I use split on a string two times in a row using piping?

Let's say I have the following string dog.puppy/cat.kitten/bear.cub. I want to get bear only. I can do this by executing the following:
$str = "dog.puppy/cat.kitten/bear.cub"
$str = $str.split('/')[2]
$str = $str.split('.')[0]
Am I able to get bear using one line using piping? This doesn't work, but it would be something like this:
$str = "dog.puppy/cat.kitten/bear.cub"
$str = $str.split('/')[2] | $_.split('.')[0]
Am I able to get "bear" using one line using piping?
With strings already stored in memory, there is no good reason to use the pipeline - it will only slow things down.
Instead, use PowerShell's operators, which are faster than using a pipeline and generally more flexible than the similarly named .NET [string] type's methods, because they operate on regexes (regular expressions) and can also operate on entire arrays:
PS> ('dog.puppy/cat.kitten/bear.cub' -split '[/.]')[-2]
bear
That is, split the input string by either literal / or literal . (using a character set, [...]), and return the penultimate (second to last) ([-2]) token.
See this answer for why you should generally prefer the -split operator to the String.Split() method, for instance.
The same applies analogously to preferring the -replace operator to the String.Replace() method.
It's easy to chain these operators:
PS> ('dog.puppy/cat.kitten/bearOneTwoThree.cub' -split '[/.]')[-2] -csplit '(?=\p{Lu})'
bear
One
Two
Three
That is, return the penultimate token and split it case-sensitively (using the -csplit variation of the -split operator) whenever an uppercase letter (\p{Lu}) starts, using a positive look-ahead assertion, (?=...).
You can do this:
$str = "dog.puppy/cat.kitten/bear.cub".split('/')[2].split('.')[0]
No piping needed.
There is an easier solution,
the .split() method uses each char to split,
using a negative index counts from back, so
> "dog.puppy/cat.kitten/bear.cub".split( '/.')[-2]
bear
Your other question can be solved with the RegEx based -csplit operator using a
nonconsuming positive lookahead and
a final -join ' ' to concatenate the array elements with a space.
$str = "dog.puppy/cat.kitten/bearOneTwoThree.cub"
$str = $str.split('/.')[-2] -csplit '(?=[A-Z])' -join ' '
$str
bear One Two Three

Need to use regular expressions inside of a function to match a string passed to it

What I'd like to do is create a function that is passed a string to match a regular expression inside of the function. Let's call the function "matching." It should use the -match command. I want it to meet the criteria:
The < character
Four alphabetic characters of upper of lowercase (a-z or A-Z)
The > character
The - character
Four digits, 0-9
So basically it would just look like "matching whateverstringisenteredhere" then it'd give me true or false. Probably incredibly simple for you guys, but to someone new at powershell it seems really difficult.
So far I have this:
function matching ($args0)
{
$r = '\b[A-Za-z]{4}[0-9]{4}<>-\b'
$r -match ($args0)
}
The problem seems to be it's not treating it as a regular expression inside the function. It's only taking it literally.
The regex goes on the right side of the -match operator and the string to be matched goes on the left. Try:
$args0 -match $r

Perl Search and Replace — issues is caused by "\"

I am parsing a text doc and replacing some text. Lines of text without the "\" seem to be found and replaced no issues.
By the way this is to be done in Perl
I have a string like below:
Path=S:\2014 March\Test Scenarios\load\2014 March
that contains "\" that slash is an issue. I am using a simple search and replace line of code
$nExit =~ s/$sMatchPattern/$sFullReplacementString/;
How should I do it?
I suspect that you're trying to match a literal string, and therefore need to escape regex special characters.
You can use quotemeta or the escape codes \Q ... \E to do that:
$nExit = s/\Q$sMatchPattern/$sFullReplacementString/;
The above variable $sMatchPattern will be interpolated, but then any special characters will be escaped before the regex is compiled. Therefore the value of $sMatchPattern will be treated like a literal string.
Is this string inputed, or is it embedded in your program. You could do this to get rid of the backslash character:
my $path = "S:/2014 March/Test Scenarios/load/2014 March";
By the way, it's best not to have spaces in file and path names. They can be a bit problematic in certain situations. If you can't eliminate them, it's understandable.
Two things you should look at:
Use quotemeta which can help quote special characters in strings and allow you to use them in substitutions. Even if you had backslashes in your strings, quotemeta will handle them.
You don't have to use / as separators in match and substitutions. Instead, you can substitute various other characters.
These are all the same:
$string =~ s/$regex/$replace/;
$string =~ s#$regex#$replace#;
$string =~ s|$regex|$replace|;
You can also use parentheses, square braces, or curly brackets:
$string =~ s($regex)($replace);
$string =~ s[$regex][$replace]; # Not really recommended because `[...]` is a common regex
$string =~ s{$regex}{$replace};
The advantage of these as regular expression quote-like characters is that they must be balanced, so if I had this:
my $string = "I have (parentheses) in my string";
my $regex = "(parentheses}";
my $replace = "{curly braces}";
$string = s($regex)($replace);
print "$string\n"; # Still works. This will be "I have {curly braces} in my string"
Even if my string contains these types of characters, as long as they're balanced, everything will still work.
For yours:
my $Path = 'S:\2014 March\Test Scenarios\load\2014 March';
$nExit = quotemeta $string; #Quotes all meta characters...
$nExit =~ s($sMatchPattern)($sFullReplacementString);
That should work for you.
if you want to have a \ in your replacement string or match string dont forget to put another backslash in front of the backslash you want, as its an operator...
$sFullReplacementString = "\\";
That would turn the string into a single \