如何使用正则表达式解析和区分用户命令的不同和变化的参数?

How to parse and distinguish different and varying arguments of a user command with a regular expression?

我正在尝试将用户命令解释为破折号可选标志。

{run -o -f -a file1 file2}

像这样:

/{run (-o|-f) (\w+) (.+?)}/g;

非常有限,只有 1 个标志选择。

我正在寻找一个正则表达式,它可以正确解析带有任意数量破折号标志的字符串,将标志分成组,而不用担心中间有一定数量的空白。

string = "{run    -a  file1 file2}"
string = "{run    -a -o -f  file1 file2}"
string = "{run -f-a-o  file1 file2}"

string.match(regex) 应该输出每个标志和每个文件名。

示例输出为:

["f", "a", "o", "file1", "file2"]

或者如果不可能,像这样:?

["-f-a-o", "file1", "file2"]

单个正则表达式最多能够捕获 9 个组。

因此...... “解析[ing]带有任意数量破折号标志的字符串”......就像OP一样,单独的正则表达式无法实现需求.

一个足够好的方法是 capture both groups, the flags sequence and the files sequence 然后将它们处理成一个由分隔的 标志 文件名 [=55= 组成的串联列表] 项 ...

// see ... [https://regex101.com/r/VFjeK1/1]
const regXFlagsAndFiles =
  (/^\{\s*run(?:\s+-(?<flags>[a-z]+(?:\s*-[a-z]+)*))*\s+(?<files>[\w.]+(?:\s+[\w.]+)*)\s*\}$/);
  
function parseFlagAndFileList(value) {
  const {
    flags,
    files,
  } = regXFlagsAndFiles
    .exec(String(value))
    ?.groups || {};

  return (flags
    ?.split(/\s*-\s*/)
    ?? []
  ).concat(
    files
      ?.split(/\s+/)
      ?? []
  );
}

console.log([

  '{run file1 file2}',
  '{run    -a  file1 file2}',
  '{run    -a -o -f  file1 file2}',
  '{run -f-a-o  file1 file2}',

].map(parseFlagAndFileList));

console.log([

  '{run}',
  '{run      }',
  '{run file1  }',
  '{run    -abc  file1.foo file2.bar  }',
  '{run    -ab -ogg -fgg  file1.baz file2  }',
  '{run -f-a-ob  file1 file2.biz  }',
  '{ run -a -b       }',
  '{ fun -a -b       }',

].map(parseFlagAndFileList));
.as-console-wrapper { min-height: 100%!important; top: 0; }

一个正则表达式几乎涵盖了 OP 希望只用一个简单的模式来完成所有事情的愿望,看起来像这个……/[\w.]+/g

这是原因...

// see ... [https://regex101.com/r/VFjeK1/3]
const regXCommandTokens = (/[\w.]+/g);

console.log([

  '{run file1 file2}',
  '{run    -a  file1 file2}',
  '{run    -a -o -f  file1 file2}',
  '{run -f-a-o  file1 file2}',

].map(command => command.match(regXCommandTokens).slice(1)));

console.log([

  '{run}',
  '{run      }',
  '{run file1  }',
  '{run    -abc  file1.foo file2.bar  }',
  '{run    -ab -ogg -fgg  file1.baz file2  }',
  '{run -f-a-ob  file1 file2.biz  }',
  '{ run -a -b       }',
  '{ fun -a -b       }',

].map(command => command.match(regXCommandTokens).slice(1)));
.as-console-wrapper { min-height: 100%!important; top: 0; }