Search code examples
regexnotepad++

Is there a better way to write this incredibly long regex, or perform this error check?


I was trying to find a way to error/style correct a non-standard custom menu file from a decade old video game that I was working on in Notepad++ and this was the best I could come up with.

The below returns any curly brackets that aren't followed by an EOL character or are preceded by anything other than line start and 1-4 tabs, it works fine but seems like it could be a lot more elegant. Any returned brackets are incorrect unless they're the first or last in the file. More tabs are technically okay highly unlikely.

    (?<!^\t)(?<!^\t\t)(?<!^\t\t\t)(?<!^\t\t\t\t)[{}]|[{}](?!\R)

Properly formatted:

    Menu "MenuName"
    {
        Menu "SubMenuName"
        {
            Option "OptionName" "Command"
            Option "OptionName" "Command"
        }
    }
// This is a comment line
// [ curly brackets in comment lines are made square so they don't get counted as balancing

All curly brackets should be on a separate line by themselves with nothing but preceding tabs. They should also be paired but I've got a plugin handling that.

Improperly formatted:

    Menu "MenuName"{
        Menu "SubMenuName"
        {
            Option "OptionName" "Command"
            Option "OptionName" "Command"   }
    }Menu "That bracket would be wrong since the line should end afterwards.
    {   //this would also be wrong
// Nothing should ever follow a bracket except a End Of Line character.

Is there some better way to implement this search/check, considering Notepad++ uses Boost regex and doesn't allow variable-length lookbehinds? Also perhaps keeping in mind that I learned everything I know about regex last night.

The expression also returns the first (no preceding tab) and last (no EOL character) but I'm okay with that particular behavior.


The full content of a file I use as a template:

It loads from a loose file in the data folder, completely as is.

//DO NOT DELETE, needs a line here for some reason.
Menu "MenuNameTEMPLATE"
{
    Title "TitleName"
    Option "OptionName" "Command"
    Divider
    LockedOption
    {
        DisplayName "OptionName"
        Command "Command"
        Icon "IconName"
        PowerReady "PowerIdentifiers"
    }
    LockedOption
    {
        DisplayName "OptionName"
        Command "Command"
        Icon "IconName"
        Badge "BadgeIdentifiers"
    }
    LockedOption
    {
        DisplayName "OptionName"
        Command "Command"
        Icon "IconName"
    }
    Menu "SubMenuName"
    {
        Title "TitleName"
        Option "OptionName" "Command"
        Option "OptionName" "Command"
    }
}

Solution

    • Ctrl+F
    • Find what: ^\h+[{}](?=\h*\R)(*SKIP)(*FAIL)|[{}]
    • CHECK Wrap around
    • CHECK Regular expression
    • Find All in Current Document

    Explanation:

      ^                   # beginning of line
        \h+                 # 1 or more horizontal spaces, you can use \t{1,4} if you only want tabulations
        [{}]                # open or close brace
        (?=                 # positive lookahead, make sure we have after:
            \h*                 # 0 or more horizontal spaces
            \R                  # any kind of linebreak
        )                   # end lookahead
        (*SKIP)(*FAIL)      # skip this match and consider that fails
    |                   # OR
        [{}]                # open or close brace
    

    Screenshot:

    enter image description here