Search code examples
arrayspowershellspecial-charactersstring-matching

How do I remove characters like "?" from an array powershell


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.  

}
}

Solution

  • # 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.