如何使用正则表达式解析和区分用户命令的不同和变化的参数?
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; }
我正在尝试将用户命令解释为破折号可选标志。
{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; }