Regex to get any text enclosed in []

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Curtis Smith Curtis Smith 6 months, 4 weeks ago.

  • Author
    Posts
  • #39075
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    I have a number of text that are sql logs with an example below(Ive changed the name of the text in them:

    What I would like to select all the text within the [] minus the dbo . Then add them to a collection. I'll try to figure out how to add them to an object, but I think I need some help in extracting out the text in the [].

    Command: ALTER INDEX [CTSO_GEN_ACCT] ON [CTSO_DB].[dbo].[GEN_ACCOUNT] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE =ON)
    
    

    Any help would be appreciated.

  • #39077
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    I think this is what you are looking for. Let me know if you have any questions about what is going on here.

    $regex = [regex]"\[([^dbo].*?)]"
    $collection = $regex.matches("Command: ALTER INDEX [CTSO_GEN_ACCT] ON [CTSO_DB].[dbo].[GEN_ACCOUNT] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE =ON)") |
    ForEach-Object {
        $_.Groups[1].value
    }
    $collection
    

    Results:

    CTSO_GEN_ACCT
    CTSO_DB
    GEN_ACCOUNT
    

    Here is another example of the same thing being done a little differently. More POSHish.

    $msg = "Command: ALTER INDEX [CTSO_GEN_ACCT] ON [CTSO_DB].[dbo].[GEN_ACCOUNT] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE =ON)"
    $collection = $msg | 
    Select-String "\[([^dbo].*?)]" -AllMatches |
    Select-Object -ExpandProperty Matches |
    ForEach-Object {
        $_.groups[1].value
    }
    $collection
    

    Same Results:

    CTSO_GEN_ACCT
    CTSO_DB
    GEN_ACCOUNT
    
  • #39081
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Thank you Curtis,

    The result is what I am after to extract the string...however the text that I am seeing comes in text paragraphs and refer to this one. . I can do another post to refer to this one.

  • #39084
    Profile photo of random commandline
    random commandline
    Participant

    I have a few questions. I need some clarification on your use of '.*' and '?' symbols.
    Why does the following not display multiple values? I thought the use of '.*' means zero or more of any character will match. Which means the following should display all matches between brackets.

    $string = "Command: ALTER INDEX [CTSO_GEN_ACCT] ON [CTSO_DB].[dbo].[GEN_ACCOUNT] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE =ON)" 
    [regex]::Matches($string,"\[(.*)]").value 
    #Result:  [CTSO_GEN_ACCT] ON [CTSO_DB].[dbo].[GEN_ACCOUNT] 
    

    A question mark matches zero or one of the preceding character,class or subpattern.

    [regex]::Matches($string,"\[(.*?)]").value
    #Result:  [CTSO_GEN_ACCT]
    #Result:  [CTSO_DB]
    #Result:  [dbo]
    #Result:  [GEN_ACCOUNT] 
    

    If I understand correctly, the '?' symbol, will display all captures between brackets, but nothing starting with 'dbo'.

    [regex]::Matches($string,"\[([^dbo].*?)]").value
    #Result:  [CTSO_GEN_ACCT]
    #Result:  [CTSO_DB]
    #Result:  [GEN_ACCOUNT] 
    
  • #39086
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    @random-commandline
    The ? character in this case tells .* to not be greedy, meaning it will match the fewest characters for fulfill the match rather than the most characters to fulfill the match. Let me give an example.

    with the regular expression

    \[(.*)]

    and the string

    123[456]789[abc]def

    it will match

    [456]789[abc]

    since it will find as may characters as it can between an [ and ], even if those characters themselves are [ and ] characters.

    If you want each individual set, you have to tell it to not be greedy. It will match all characters up until it finds the next set of characters to complete the pattern, then it stops. A new match is found if the pattern repeats.

    with the regular expression

    \[(.*?)]

    and the string

    123[456]789[abc]def

    it will find matches

    [456]
    [abc]

You must be logged in to reply to this topic.