1

I am trying to validate strings of text taken from PC descriptions in Active Directory.
But I want to remove rogue characters like a single value of "??" from any text before validating any text.

I have this test code as an example. But whenever it hits the random character "??" It throws this error:
Error:

parsing "??" - Quantifier {x,y} following nothing.
At C:\Users\#####\OneDrive\Workingscripts\testscripts\removeingfromarray.ps1:11 char:5
+ If ($charigmorematch -match $descstr)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

When all I want to do is remove it from the array! Any help greatly appreciated.

This is the example code I have.

##Type characters to remove in array.
$charigmorematch = @("?"; "@"; "$")
##array declare
$userdesc = @()

###Where this would be an AD description from AD.  
$ADUser = "Offline - ?? - test"

###Split AD Descrip into individual strings
$userdesc = $ADUser.Split("-").Trim()

###Run through them to check for rogue characters to remove
ForEach($descstr in $userdesc)
{

###If match found try and take it out
If ($charigmorematch -match $descstr)
{

###Store match in variable.  
$strmatch = ($charigmorematch -match $descstr)

###Get the index of the string
$indexstr = $userdesc.indexof($descstr)

Write=host "Match: $strmatch Index: $indexstr"
###Once found a match of a rogue character then remove from the array!
##But I haven't figured out that code yet.  

###Then a command to remove the string from the array with the index number.
###In this case it's likely to be [1] to remove. But the code has to work that out.  

}
}
  • 3
    Why not simply do `-replace '[?@$]'` ? If you use `-match` on the characters you need to escape the `?` and `$` with a backslash because these have special meaning in regex. – Theo Jul 23 '22 at 12:47
  • Are you just splitting the string because you want to remove these chars, or do you need an array as the result? If not, then Theo's solution will easily fit. You may also want to remove the "-" then. @Theo you don't need to escape it. $ADUser -match "[?@$]+" is fine. – Sven Jul 23 '22 at 12:53
  • @Sven I'm not escaping it because I'm using the characters inside `[]`. However, if you want to use `-match` on each of the characters separately as the OP is trying to do, you need to escape. (maybe my wording wasn't clear there..) – Theo Jul 23 '22 at 13:22
  • I am splitting the string into an array to use for later for further work. But I need to remove any characters like the ? and the like. So once the '??' is removed from the array I should have an array with only 2 strings: Result: Offline test – Iain Howard Jul 23 '22 at 14:15
  • I did try a code replace but this way: but it was pulling in all strings and replacing them with 'ignorestring' ``` If ($userstr -like '*?*') { $userstr = "ignorestring" } ``` – Iain Howard Jul 23 '22 at 14:24
  • The -like "*?*" had wildcards in it but I abandoned that idea cause it was causing problems and changing all the strings. – Iain Howard Jul 23 '22 at 14:47
  • I have code that validates if a descriptions contains "-" or "|" and based on these characters it will split the description. There is also a split in a space but that's for different criteria. This comment may not be relevant to the problem but just adding so you understand more of what I am trying to do. – Iain Howard Jul 23 '22 at 14:58
  • I've added some further explanations in the code above. Thanks. – Iain Howard Jul 23 '22 at 15:14
  • Did you try this? ```$ResultArray = $ADUser.Split("-") | Where-Object { !($_ -match "[\$\?\@]") } ``` – Sven Jul 23 '22 at 18:17
  • I'll try that and let you know if it's a workable solution. – Iain Howard Jul 23 '22 at 18:36

1 Answers1

0
# Sample input.
$ADUser = "Offline - ?? - test"

# Split into tokens by "-", potentially surrounded by spaces,
# and filter out tokens that contain '?', '@', or '$'.
($ADUser -split ' *- *') -notmatch '[?@$]'

The result is the following array of tokens: 'Offline', 'test'

Note that -notmatch, like all comparison operators that (also) operate on strings, acts as a filter with an array as the LHS, as is the case here (-split always returns an an array).


Based on the additional requirements you mentioned in later comments, you're probably looking for something like this (splitting by - or |, trimming of surrounding (...)):

# Sample input
$ADUser = "Notebook PC | (Win 10) | E1234567 - simple ^^ user | Location ?? not @ set" 

($ADUser -split ' *[-|] *') -notmatch '[?@$]' -replace '^\(|\)$'

This results in the following array of tokens:
'Notebook PC', 'Win 10', 'E1234567', 'simple ^^ user'

Note that unless your input strings have leading or trailing spaces, there is no need for calling .Trim()


As for what you tried:

$charigmorematch -match $descstr

The -match operator:

  • requires the input string(s) to be the LHS (left-hand side) operand.

  • requires a regex (regular expression) as the RHS (right-hand side) operand, to formulate a pattern that the input is matched against.

By contrast, your attempted operation:

  • mistakenly reversed the order of operands ($descstr, as the string in which to look for regex patterns must be the LHS).

  • mistakenly used an array as the comparison pattern ($charigmorematch), instead of a (single) regex (expressed as a string) that uses a character set ([...]) to specify the characters of interest.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Wow!! It seems I can eliminate 192 lines of code with this one line of code: ($ADUser -split ' *[-|] *') -notmatch '[?@$]' -replace '^\(|\)$ – Iain Howard Jul 24 '22 at 08:49