regex question

hi all,

I’m still learning Regex and I cannot figure out how to check if a string is present or not, depending on 2 values.

Reading the registry keys, I need to see if VISSTD or VISPRO is present.

here’s an example: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Office16.VISSTD

I need a regex that would capture either VISSTD (as shown here) or VISPRO. All my attemps are in vain.

Thank you!

That doesn’t matter. You should show it anyway. We’re much better with tweaking existing code even if it’s poor than writing ready to use code from scratch. :wink:

The simplest regex pattern would be “VISSTD|VISPRO”.

that was so simple.

thanks!

Echoing this. It’s hard to troubleshoot blind - and PowerShell has a couple different methods by which regex could be applied, especially depending on what the input looks like (e.g. are you holding the registry subkeys in an array? dumping them into a text file? trying to check them one at a time?)

Really, the starting point for using regex is thinking about what your input data set looks like, and how to specify exactly what you want and not the things you don’t want. This is hard with registry subkeys because there are a lot of them and they’re not really consistently named. If you have plugins or libraries or third party tools related to Visual Studio, but you only want to find registry subkeys for the application itself, those other things might produce false positives if you’re not specific with the regex.

So, let’s run a few examples. Here’s a set of options and a simple regex filter:

$opts = @("Office16.VISSTD","Office16.VISPRO","Office13.VISPRO","Office16.VISNOT","office16.visstd","foovisstdbar","office16.word")
$slct = $opts -match 'VIS'
$slct

This gives us

Office16.VISSTD
Office16.VISPRO
Office13.VISPRO
Office16.VISNOT
office16.visstd
foovisstdbar

which obviously isn’t very good because it matches other things that contain “vis”. One option would be to perform a case match like this:

$slct = $opts -cmatch 'VIS'

which gives

Office16.VISSTD
Office16.VISPRO
Office13.VISPRO
Office16.VISNOT

which looks a little better because it only matches strings containing the capitalized “VIS”. But, this assumes that the registry subkeys will be consistently capitalized, which may not be reliable. So not the best option. Olaf’s regex is more specific:

$slct = $opts -match 'VISSTD|VISPRO'
Office16.VISSTD
Office16.VISPRO
Office13.VISPRO
office16.visstd
foovisstdbar

but if you have multiple versions of Visual Studio installed (or for some reason, registry subkeys that contain either “visstd” or “vispro”) it may give you things that you don’t want. So, let’s trim it a bit further:

$slct = $opts -match 'Office.*VIS(STD|PRO)'
Office16.VISSTD
Office16.VISPRO
Office13.VISPRO
office16.visstd

This gives us only results that have “office” followed by “vis” followed by either “std” or “pro” (the part in parentheses is a subexpression). The period after “Office” in the regex string matches any single character, and the asterisk after the period allows any number of matches. This accounts for the “16.” or “13.” betweeen “Office” and “VIS” in the data set, but note that it would match any characters that happened to be in there, so it may not be specific enough (it may produce false positives). If we only want Visual Studio 2016 versions, we can do this:

$slct = $opts -match 'Office16.VIS(STD|PRO)'
Office16.VISSTD
Office16.VISPRO
office16.visstd

That’s better, but not if we want all installations of Visual Studio regardless of version. For that, we can do this:

$slct = $opts -match 'Office[0-9]*.VIS(STD|PRO)'
Office16.VISSTD
Office16.VISPRO
Office13.VISPRO
office16.visstd

This will match any string like “office##.visstd” or “office##.vispro”, so it will capture all version years if necessary (and should produce few, if any, bad matches).