简体   繁体   中英

Regex help needed: pattern almost works

I am needing a bit of help with regular expressions for ECMAScript. The regex I am currently using almost works as desired, but there is a small hiccup. I need to match the following:

STAT or STATS regardless of case. Additionally, there may be symbols and numbers that follow.

Example: stats:3-2 is a match. stats:5 is a match. stats-4 is a partial match, but the '-4' should be ignored.

The current regex I am using, as already noted, almost works and is as follows: /STAT[S]*(?:(?:[\:](?<method>(\d)))(?:[\-](?<count>(\d)+))*)*/ig

This pattern, using regex101, actually matches all conditions and ignores the -4 in the following example: stats-4 , while matching the word 'stats'.

However, when I attempt to use this pattern in a plugin that I am editing, problems arise. It currently only matches stat , stats , stat:2 , but not stat:3-2 , stat-4 (which should match the 'stat' but ignore the '-4').

I am aware the pattern may be a bit messy, but I am not good with creating regular expressions.

Exact usage (in atom rpg-dice plugin):

    roll() {
        const editor = atom.workspace.getActiveTextEditor();
        const regex = [
            /(\+|\-){1}([\d]+)/i,
            /([\d]+)d([\d]+)(?:([\+|\-]){1}([\d]+))*/i,
            /STAT[S]*(?:(?:[\:](?<method>(\d)))?(?:[\-](?<count>(\d)+))*)*/i
        ];

        if (editor) {
            // attempt to select the dice roll
            let selection = editor.getSelectedText();
            // if the selection failed, try selection another way.
            if (selection.length < 1) {
                editor.selectWordsContainingCursors();
                atom.commands.dispatch(atom.views.getView(editor), 'bracket-matcher:select-inside-brackets');
                selection = editor.getSelectedText();
            }
            // increase size of selection by 1, both left and right. (selects brackets)
            let range = editor.getSelectedBufferRange();
            let startColumn = range.start.column -1;
            let endColumn = range.end.column +1;
            editor.setSelectedBufferRange([[range.start.row, startColumn],[range.end.row, endColumn]]);
            // trim any whitespace from the selection
            selection.trim();

            /*
                regex pattern matching to determine the
                type of roll.
             */
             if (matches = selection.match(regex[0])) {                          // 1d20 roll; attack and ability checks
                type = 'check';
             } else if (matches = selection.match(regex[1])) {                   // typically a damage dice roll
                type = 'dmg';
             } else if (matches = selection.match(regex[2])) {                   // used for stat generation
                console.log(matches);
             } else {
                console.log('Cannot determine a suitable use.');
             }
     

You can use

/STATS?(?::(?<method>\d)(?:-(?<count>\d+))?)?/gi

See the regex demo . Details :

  • STATS? - STATS or STAT
  • (?::(?<method>\d)(?:-(?<count>\d+))?)? - an optional occurrence of
    • : - a colon
    • (?<method>\d) - Group "method": a single digit
    • (?:-(?<count>\d+))? - an optional occurrence of
      • - - a hyphen
      • (?<count>\d+) - Group "count": one or more digits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM