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

Time:03-19

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 as a loose file from the data folder.

//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"
    }
}

CodePudding user response:

  • Ctrl F
  • Find what: ^\h [{}](*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
    (*SKIP)(*FAIL)      # skip this match and consider that fails
  |                   # OR
    [{}]                # open or close brace

Screenshot:

enter image description here

CodePudding user response:

I want to start by saying that regex is 100% the wrong tool for this, you want a custom parser to handle both validating your file and parsing it into a model you can then use.

However, with the limitations imposed by your question, the following should do it:

^(?:[^{}]*|\t{1,4}[{}])$

Rather than worry about look-arounds, simply match what you expect to find. See it in action here: https://regex101.com/r/nYNqHw/1

  • Related