0

我正在编写一个模拟器,并想通过调用模拟器的许多实例,使用不同的命令行参数集来运行研究。我已经阅读了这个问题和其他几个问题,它们看起来很接近,但我实际上并不是在寻找满足特定正则表达式的随机数据,我想要与正则表达式匹配的所有字符串的集合。示例输入文件如下所示:

myprogram.{version1|version2} -arg1 {1|2|4} {-arg2|}

或者:

myprogram.{0} -arg1 {1} {2}
0: "version1" "version2"
1: "1" "2" "4"
2: "-arg2" ""

并会产生:

myprogram.version1 -arg1 1 -arg2
myprogram.version1 -arg1 1
myprogram.version1 -arg1 2 -arg2
myprogram.version1 -arg1 2
myprogram.version1 -arg1 4 -arg2
myprogram.version1 -arg1 4
myprogram.version2 -arg1 1 -arg2
myprogram.version2 -arg1 1
myprogram.version2 -arg1 2 -arg2
myprogram.version2 -arg1 2
myprogram.version2 -arg1 4 -arg2
myprogram.version2 -arg1 4

我想像这样的东西已经存在,我只是不知道要搜索的正确术语。任何帮助将非常感激。如果需要,我可以自己实现一种抽象技术或算法,但如果它是一个预先存在的工具,我希望它是免费的(至少像啤酒一样)并在 Linux 上运行。

我知道我可能会遗漏一些细节,如果有必要,可以更具体地说明适当的事情,而不是预先用大量细节淹没人们。我完全有可能以错误的方式解决这个问题,我欢迎所有解决方案,即使它们以不同的方式解决我的问题。

最重要的是,如果我想向我生成的字符串的“叉积”添加更多参数选项,此解决方案不应该要求我编写任何额外的解析代码。我已经有一个 Perl 脚本,它在每个“变量”上使用一组嵌套for循环来执行此操作,每次我更改变量的数量或性质时,这些“变量”都必须更改。

4

2 回答 2

3

只要大括号没有嵌套,正则表达式就可以正常工作。如果您需要嵌套,您可以在实现语言中添加一些额外的递归。

以下是 Python 中的示例:

import re

def make_choices(template):
    pat = re.compile(r'(.*?)\{([^{}]+)\}',re.S)

    # tokenize the string
    last_end = 0
    choices = []
    for match in pat.finditer(template):
        prefix, alts = match.groups()
        if prefix:
            choices.append((prefix,)) # as a tuple
        choices.append(alts.split("|"))
        last_end = match.end()

    suffix = template[last_end:]
    if suffix:
        choices.append((suffix,))

    # recursive inner function
    def chooser(index):
        if index >= len(choices):
            yield []
        else:
            for alt in choices[index]:
                for result in chooser(index+1):
                    result.insert(0,alt)
                    yield result

    for result in chooser(0):
        yield ''.join(result)

例子:

>>> for result in make_choices('myprogram.{version1|version2} -arg1 {1|2|4} {-arg2|}'):
...     print result
...
myprogram.version1 -arg1 1 -arg2
myprogram.version1 -arg1 1
myprogram.version1 -arg1 2 -arg2
myprogram.version1 -arg1 2
myprogram.version1 -arg1 4 -arg2
myprogram.version1 -arg1 4
myprogram.version2 -arg1 1 -arg2
myprogram.version2 -arg1 1
myprogram.version2 -arg1 2 -arg2
myprogram.version2 -arg1 2
myprogram.version2 -arg1 4 -arg2
myprogram.version2 -arg1 4

您可以使用os.system()从 Python 中执行命令:

#!/etc/env python
import sys, os

template = ' '.join(sys.args)
failed = 0
total = 0
for command in make_choices(template):
    print command
    if os.system(command):
        print 'FAILED'
        failed += 1
    else:
        print 'OK'
    total += 1

print
print '%d of %d failed.' % (failed,total)

sys.exit(failed > 0)

然后在命令行上:

user:/home/> template.py 'program.{version1|version2}'
program.version1
OK
program.version2
FAILED

1 of 2 failed.
于 2009-06-18T22:38:20.857 回答
2

您并不是真的在寻找正则表达式所设计的东西。您只是在寻找一种生成离散选项组合的工具。

根据所有可能参数的集合,实际上可能不需要详尽的组合列表。无论如何,您应该研究成对测试。我知道PICT 工具可以为您生成详尽的列表或您想要的测试用例的成对列表。

于 2009-06-18T23:01:20.173 回答