是否可以在一行中检测捕获组的组合和排列?

Posted

技术标签:

【中文标题】是否可以在一行中检测捕获组的组合和排列?【英文标题】:Is it possible to detect combinations and permutations of captured groups in a single line? 【发布时间】:2021-10-15 11:35:16 【问题描述】:

我正在尝试从进程表中检测一个程序,我需要在捕获的组中解析它的参数。我想用一个正则表达式来做到这一点,但是,我不知道是否有可能某些参数被混淆和/或省略。

例如,我有:

program.exe -a arg_a -b arg_b -c arg_c -d arg_d -e arg_e

但也可以是:

program.exe -c arg_c -a arg_a -b arg_b -e arg_e
program.exe -b arg_b 
program.exe -a arg_a -c arg_c -d arg_d

现在,我需要获取每个参数。我知道我可以简单地拥有 5 组正则表达式,如下所示,

"program.exe(?:.*-a (?<arga>\w+)|)"
"program.exe(?:.*-b (?<argb>\w+)|)"
"program.exe(?:.*-c (?<argc>\w+)|)"
"program.exe(?:.*-d (?<argd>\w+)|)"
"program.exe(?:.*-e (?<arge>\w+)|)"

但这需要 5 次迭代,我真的很想一次运行。

有可能吗?非常感谢您对此的任何见解。

【问题讨论】:

【参考方案1】:

您可以使用这样的正则表达式来匹配整个字符串:

^program.exe(?:\s+-(?<name>[a-e]) (?<arg>\w+))+$

然后使用Captures 属性:

string regex = @"^program.exe(?:\s+-(?<name>[a-e]) (?<arg>\w+))+$";
string text = "program.exe -a arg_a -d arg_d -e arg_e -b arg_b -c arg_c";
Match match = Regex.Match(text, regex);
var names = match.Groups["name"];
var args = match.Groups["arg"];
foreach (var (name, arg) in names.Captures.Zip(args.Captures)) 
    Console.WriteLine($"name.Value: arg.Value");
    // or add these pairs to a dictionary for further processing and validation


/*
a: arg_a
d: arg_d
e: arg_e
b: arg_b
c: arg_c
*/

【讨论】:

【参考方案2】:

当然,让你的正则表达式像

-(?<arg>[a-e]) (?<val>\w+)

运行它,你会得到 n 个匹配项,其中 n 是参数的数量,然后你可以循环它们

如果您将它们分配给字典并拥有读取字典的道具,则提供它们的顺序无关紧要

foreach(var m in r.Matches(...))
  args[m.Groups["arg"].Value] = m.Groups["val"].Value;

(也可以使用 LINQ 来处理那个位..)

然后是一些道具,例如:

public string ArgumentE  get => args.TryGetValue("e", out string s) ? s ; "default"; 

这样你的代码就可以了

if(ArgumentE == "White")
  ...

【讨论】:

以上是关于是否可以在一行中检测捕获组的组合和排列?的主要内容,如果未能解决你的问题,请参考以下文章

Lotto(DFS处理)

Python 排列组合

如何组合多行数据,直到下一行值在 SQL Server 中不为空

组合数问题 vijos2006 NOIP2016 D2T1 杨辉三角 排列组合 前缀和

luogu2714 四元组统计 莫比乌斯反演 组合数

HihoCoder1639 : 图书馆([Offer收割]编程练习赛36)(组合数学)