Powershell capture text within quotes - powershell

I have a line saved as $variable1, for example:
file"yourtxthere/i/master.ext" autostart:true, width
How would I go about writing the correct syntax using Regex in Powershell to grab everything within the quotes. Are regular expressions the best way to do this in Powershell?

Though regular expressions are powerful, this is a simple case. Thus a simple solution is based on string object's split() method.
$variable1 = 'file"yourtxthere/i/master.ext" autostart:true, width'
# Splitting requires at least one "
if ($variable1.IndexOf('"') -gt 0) {
$variable1.Split('"')[1]
}
Splitting the string will result an array of three elements:
file
yourtxthere/i/master.ext
autostart:true, width
As Powershell's arrays begin with index zero, the desired data is at index location 1. In case the string doesn't contain a double quote, the split won't work. This is checked with the statement
if ($variable1.IndexOf('"') -gt 0)
Without one, splitting a quoteless string would return just a one-celled array and trying to access index 1 would result in an error message:
$variable1.Split('!')[1]
Index was outside the bounds of the array.

I'm not 100% sure I understand the question but assuming you had that stored in $variable1 as a string like so:
$variable1 = 'file"yourtxthere/i/master.ext" autostart:true, width'
Then you could extract just the quoted text by splitting the string using the double quotes as a delimiter like this:
$variable1.Split('"')[1]
That splits the string into an array with three parts. The first part is everything before the first double quotes and the second everything in between the first and second quote marks, and the third everything after the second quotation marks. The [1] tells it to output the second part.
I think this picture might illustrate it a little better.
There are other ways to split that up and in fact the variable isn't necessary at all if you do something like this:
('file"yourtxthere/i/master.ext" autostart:true, width').split('"')[1]
That will work fine so long as there are never any extra double quotes before the first occurrence.

Related

Putting Powershell variable in double quotes shows Object type instead of value

I see this problem in several area, but here is an example
I read an xml document like this and print out a value
[xml]$pom = get-content -path pom.xml
PS C:\> $pom.project.artifactId
nexus-peter-test-service
However, if I put the value in double quotes, I get this
"$pom.project.artifactId"
System.Xml.XmlDocument.project.artifactId
I need the value in double quotes because it's part of a long string. In my case, a url. So I'm using it like this:
"/$pom.project.artifactId/"
Why does Powershell change the meaning of the variable when in it's double quotes? And how can I fix this?
The problem is that the interpolation stops at the period. It interpolates "$pom" - which stringifies as the class name - followed by the literal string ".project.artifactId".
To interpolate anything more complex than a simple variable name, you need to wrap $(...) around the expression:
"$($pom.project.artifactId)"

How to identify a character in a string?

I am trying to write a Powershell code to identify a string with a specific character from a filename from multiple files.
An example of a filename
20190902091031_202401192_50760_54206_6401.pdf
$Variable = $Filename.Substring(15,9)
Results:
202401192 (this is what I am after)
However in some instances the filename will be like below
20190902091031_20240119_50760_54206_6401.pdf
$Variable = $Filename.Substring(15,9)
Results:
20240119_ (this is NOT what I am after)
I am trying to find a code to identify the 9th character,
IF the 9th character = "_"
THEN Set
$Variable = $Filename.Substring(15,8)
Results:
20240119
All credit to TheMadTechnician who beat me to the punch with this answer.
To expand on the technique a bit, use the split method or operator to split a string every time a certain character shows up. Your data is separated by the underscore character, so is a perfect example of using this technique. By using either of the following:
$FileName.Split('_')
$FileName -split '_'
You can turn your long string into an array of shorter strings, each containing one of the parts of your original string. Since you want the 2nd one, you use the array descriptor [1] (0 is 1st) and you're done.
Good luck

Add-Content to txt

I'm trying to make a GUI that will print the information from a textbox into a .txt in a way that I will try to explain as well as I can.
$TextBox_UsbName.text = "TestingTesting"
$Button_SetUsbName.Add_Click({ $Value_UsbName = $TextBox_UsbName.text; add-content -path $Value_NewScriptPath -value "$usbname = $Value_UsbName" })
After this is run I was hoping the text file would contain this:
$usbname = "TestingTesting"
I am still new to Powershell as well as coding in general and now I am really stuck I have tried a lot of different ways.
Any ideas and help would be much appreciated.
Edit: My result is
=
In Powershell double quoted string literals, string interpolation takes place each time an unescaped $ appears with a valid identifier characters after it. To introduce a literal $ that should not be parsed as part of an interpolated variable, you should escape it with a backtick, `.
Here is some quick string interpolation help:
How do I expand an expression in a string?
Windows PowerShell will expand a variable or an expression in a string.
Variables look like: $variable
Expressions look like: $(expression)
So, your "$usbname = $Value_UsbName" is interpreted by the engine as value of $usbname variable followded with = enclosed with spaces, and then a value of $Value_UsbName variable.
What you want to add is a literal $usbname substring and the value of $TextBox_UsbName.text expression.
So, either use
"`$usbname = $($TextBox_UsbName.text)"
Or just concatenate values (in a culture independent way):
$usbname + ' = ' + $TextBox_UsbName.text

finding a comma in string

[23567,0,0,0,0,0] and other value is [452221,0,0,0,0,0] and the value should be contineously displaying about 100 values and then i want to display only the sensor value like in first sample 23567 and in second sample 452221 , only the these values have to display . For that I have written a code
value = str2double(str(2:7));see here my attempt
so I want to find the comma in the output and only display the value before first comma
As proposed in a comment by excaza, MATLAB has dedicated functions, such as sscanf for such purposes.
sscanf(str,'[%d')
which matches but ignores the first [, and returns the next (i.e. the first) number as a double variable, and not as a string.
Still, I like the idea of using regular expressions to match the numbers. Instead of matching all zeros and commas, and replacing them by '' as proposed by Sardar_Usama, I would suggest directly matching the numbers using regexp.
You can return all numbers in str (still as string!) with
nums = regexp(str,'\d*','match')
and convert the first number to a double variable with
str2double(nums{1})
To match only the first number in str, we can use the regexp
nums = regexp(str,'[(\d*),','tokens')
which finds a [, then takes an arbitrary number of decimals (0-9), and stops when it finds a ,. By enclosing the \d* in brackets, only the parts in brackets are returned, i.e. only the numbers without [ and ,.
Final Note: if you continue working with strings, you could/should consider the regexp solution. If you convert it to a double anyways, using sscanf is probably faster and easier.
You can use regexprep as follows:
str='[23567,0,0,0,0,0]' ;
required=regexprep(str(2:end-1),',0','')
%Taking str(2:end-1) to exclude brackets, and then removing all ,0
If there can be values other than 0 after , , you can use the following more general approach instead:
required=regexprep(str(2:end-1),',[-+]?\d*\.?\d*','')

Powershell: Doubled double quotes in inline expressions

Please could anyone explain me why the following happens:
"Fancy string - Hor""ray"
# outputs correctly (only one double quote): Fancy string - Hor"ray
'Hor"ray'.Replace('"', '""')
# outputs correctly (two double quotes): Hor""ray
"Fancy string - $('Hor"ray'.Replace('"', '"'+'"'))"
#outputs correctly (two double quotes): Hor""ray
"Fancy string - $('Hor"ray'.Replace('"', '""'))"
# outputs INCORRECTLY (only one double quote): Fancy string - Hor"ray
In my opinion, developers would intuitively expect, that within "$(inline expressions)" Powershell would treat text as statements and won't interfere with the last argument of Replace('"', '""') converting it into '"' (unless the statement interpreter decides to do so).
Do I miss something here?
This appears to be a bug in how PowerShell parses expandable string literals.
From ยง2.3.5.2 on string literals in the PowerShell 3.0 Language Specification, the expandable-string-literal explicitly rejects the $( sequence so that sub-expression parsing will occur instead.
So it seems reasonable to expect $('""') to parse consistently, whether or not it happens to be embedded in a string literal. And clearly sub-expressions are parsed separately, since they support values that would be illegal on their own in an expandable string (e.g. you can write "$('"')" or "$('`""')", where " '"' " or " '`""' " would fail).
However, comparing the AST from [Management.Automation.Language.Parser]::ParseInput for both $('""') and "$('""')", we get two different results. Both have a final StringConstantExpressionAst element with an Extent of '""', but the Value for the stand-alone sub-expression is "" while the Value for the embedded sub-expression is ".
Its because the inline expression is evaluated and its string value is then placed in the string and evaluated.
#Breaking "Fancy string - $('Hor"ray'.Replace('"', '""'))" down
#This inline expression is evaluated first
$('Hor"ray'.Replace('"', '""'))
#giving
Hor""ray
#That value is then interpreted as part of the string
"Fancy string - Hor""ray"
#giving
Fancy string - Hor"ray
This is exactly what I would expect to see. The inline expression evaluated and its resulting value then being used.
Could this not be done by simply using things like below:
`'$($RemFiles[$i].FullName)`'
`"$($RemFiles[$i].FullName)`"
Use the backtick and either a single or double quote to then prevent powershell from using this as an open comment, thus putting the actual symbol in...
The above outputs:
'F:\portable\adobe'
or
"F:\portable\adobe"
I noticed that it seems you are telling it to literally add two double quotes rather than just using the backtick to force it. Therefore telling it to add nothing surely :S So could you change this to something like this:
"Fancy string - $('Hor"ray'.Replace('"', '`"`"'))"
Though that may make 3, as you have one present in Hor"ray anyway.
Just got to test it, was busy with something:
PS D:\> "Fancy string - $('Hor"ray'.Replace('"', '`"`"'))"
Fancy string - Hor""ray
Scroll down on the site below to find out about the backtick and how/where it can be used.
http://www.neolisk.com/techblog/powershell-specialcharactersandtokens