Python 与给定字符集的powerset中的任何内容匹配的正则表达式

Python 与给定字符集的powerset中的任何内容匹配的正则表达式,python,regex,context-free-grammar,Python,Regex,Context Free Grammar,我正在写一个字符串模式匹配算法,我计划用正则表达式实现它。我希望正则表达式能够匹配给定字符列表的powerset中的任何字符串 我希望正则表达式以以下方式匹配: 假设我们有一份清单 s=['a','c','t','a'] 一些匹配的字符串可能是: cat, act, tac, at, aa, t, acta, taca, a aaa, tacca, iii, abcd, catk, ab 类似地,一些不匹配的字符串可能是: cat, act, tac, at, aa, t, acta, ta

我正在写一个字符串模式匹配算法,我计划用正则表达式实现它。我希望正则表达式能够匹配给定字符列表的powerset中的任何字符串

我希望正则表达式以以下方式匹配:

假设我们有一份清单 s=['a','c','t','a']

一些匹配的字符串可能是:

cat, act, tac, at, aa, t, acta, taca, a
aaa, tacca, iii, abcd, catk, ab
类似地,一些不匹配的字符串可能是:

cat, act, tac, at, aa, t, acta, taca, a
aaa, tacca, iii, abcd, catk, ab
请记住,还将考虑角色在集合中的出现次数

这也可以表示为上下文无关语法,如果这有任何帮助的话

S → A | T | C
A → aT | aC | a | aa | ɛ
T → tA | tC | t | ɛ
C → cA | cT | c | ɛ

这里的一种方法是对字符列表和传入的子字符串进行排序。然后,构建一个由应该匹配的单个字母组成的有序正则表达式模式

s = ['a','c','t','a']
s.sort()
str = ''.join(s)
substring = "at"
substring = '.*'.join(sorted(substring))
print(substring)
if re.match(substring, str):
    print("yes")

a.*t
yes
为了更详细地了解此解决方案,以下是排序后作为字符串的字符列表,后面是正在使用的正则表达式模式:

aact
a.*t

因为要在中匹配的字符串现在已排序,并且正则表达式的字符已排序,所以我们可以简单地通过......

连接字母。这里的一种方法是对字符列表和传入的子字符串进行排序。然后,构建一个由应该匹配的单个字母组成的有序正则表达式模式

s = ['a','c','t','a']
s.sort()
str = ''.join(s)
substring = "at"
substring = '.*'.join(sorted(substring))
print(substring)
if re.match(substring, str):
    print("yes")

a.*t
yes
为了更详细地了解此解决方案,以下是排序后作为字符串的字符列表,后面是正在使用的正则表达式模式:

aact
a.*t

因为要匹配的字符串现在已排序,正则表达式的字符也已排序,所以我们可以简单地通过.....

连接字母,而不使用正则表达式。使用替换循环即可轻松完成:

s = ['a','c','t','a']
test_strings = ['cat', 'act', 'tac', 'at', 'aa', 't', 'acta', 'taca', 'a',
                'aaa', 'tacca', 'iii', 'abcd', 'catk', 'ab']

for t in test_strings:
    temp = t
    for c in s:
        temp = temp.replace(c, '', 1)

    if temp == '':
        print('match: ' + t)
    else:
        print('no match: ' + t)
印刷品:

match: cat match: act match: tac match: at match: aa match: t match: acta match: taca match: a no match: aaa no match: tacca no match: iii no match: abcd no match: catk no match: ab 当然,这也将直接用于字符串:

print(is_in_powerset('acta', 'taa'))
一个优化版本,可最大限度地减少.replace调用的数量:


我会在没有正则表达式的情况下解决这个问题。使用替换循环即可轻松完成:

s = ['a','c','t','a']
test_strings = ['cat', 'act', 'tac', 'at', 'aa', 't', 'acta', 'taca', 'a',
                'aaa', 'tacca', 'iii', 'abcd', 'catk', 'ab']

for t in test_strings:
    temp = t
    for c in s:
        temp = temp.replace(c, '', 1)

    if temp == '':
        print('match: ' + t)
    else:
        print('no match: ' + t)
印刷品:

match: cat match: act match: tac match: at match: aa match: t match: acta match: taca match: a no match: aaa no match: tacca no match: iii no match: abcd no match: catk no match: ab 当然,这也将直接用于字符串:

print(is_in_powerset('acta', 'taa'))
一个优化版本,可最大限度地减少.replace调用的数量:


如果你寻找逆问题,这个问题似乎变得非常简单。 包含除a、c或t不匹配以外的任何字符的任何输入

那么,除了aa,我们永远不会看到相同的字符重复。但是aa只能位于字符串的末尾

为了解决aa问题,我们可以用一个a替换尾刺末端的任何aa,因为它们在图形上都是相同的

然后,我们可以搜索aa、cc和tt,但在任何匹配中都会失败

进口稀土 测试字符串={ “猫”:没错, “行为”:真实, "交谘会":对,, “at”:是的, “aa”:没错, “t”:是的, “acta”:没错, “塔卡”:没错, “a”:是的, “aaa”:错误, "ataa":对,, “aataa”:错, “塔卡”:错, "iii":假,, "abcd":错,, "猫":假,, “ab”:错误, “猫猫”:没错, “猫”*40000:对, “actact”:没错, } 对于测试字符串中的t、v。项目: 如果没有重新搜索^[atc]*$,t: 持续 temp=关于SUBA$,A,t 如果重新搜索^aa | aa | cc | tt,温度: 打印“不匹配%r:%s”%v,t 其他: 打印匹配%r:%s'%v,t 在上面的代码中,我用A替换aa,但是使用A也可以

还是红宝石

测试字符串={ “猫”=>正确, “act”=>正确, “tac”=>正确, 'at'=>正确, “aa”=>正确, 't'=>正确, “acta”=>正确, “塔卡”=>正确, “a”=>正确, 'aaa'=>错误, “ataa”=>正确, “aataa”=>错误, 'tacca'=>错误, “iii”=>错误, 'abcd'=>错误, 'catk'=>错误, 'ab'=>错误, “猫”=>正确, 'cat'*40000=>正确, “actact”=>正确, } 测试字符串。每个do | t,v| 温度=t.dup 如果温度匹配/^[atc]*$/ 放置“不匹配:”+t+“”+temp 下一个 终止 临时潜艇/aa$/,“A”; 如果温度匹配/aA | aA | tt | cc/ 放置“不匹配:”+t[0..80] 如果v 其他的 放置“匹配:”+t[0..80] 除非v,否则放错 终止 终止
如果你寻找逆问题,这个问题似乎变得非常简单。 包含除a、c或t不匹配以外的任何字符的任何输入

那么,除了aa,我们永远不会看到相同的字符重复。但是aa只能位于字符串的末尾

为了解决aa问题,我们可以用一个a替换尾刺末端的任何aa,因为它们在图形上都是相同的

然后,我们可以搜索aa、cc和tt,但在任何匹配中都会失败

进口稀土 测试字符串={ “猫”:没错, “行为”:真实, "交谘会":对,, “at”:是的, “aa”:没错, “t”:是的, “acta”:没错, “塔卡”:没错, “a”:是的, “aaa”:错误, "ataa":对,, “aataa”:错, “塔卡”:错, "iii":假,, "abcd":错,, "猫":假,, “ab”:错误, “猫猫”:没错, “猫”*40000:对, “actact”:没错, } 对于测试字符串中的t、v。项目: 如果没有重新搜索^[atc]*$,t: 骗局 锡; temp=关于SUBA$,A,t 如果重新搜索^aa | aa | cc | tt,温度: 打印“不匹配%r:%s”%v,t 其他: 打印匹配%r:%s'%v,t 在上面的代码中,我用A替换aa,但是使用A也可以

还是红宝石

测试字符串={ “猫”=>正确, “act”=>正确, “tac”=>正确, 'at'=>正确, “aa”=>正确, 't'=>正确, “acta”=>正确, “塔卡”=>正确, “a”=>正确, 'aaa'=>错误, “ataa”=>正确, “aataa”=>错误, 'tacca'=>错误, “iii”=>错误, 'abcd'=>错误, 'catk'=>错误, 'ab'=>错误, “猫”=>正确, 'cat'*40000=>正确, “actact”=>正确, } 测试字符串。每个do | t,v| 温度=t.dup 如果温度匹配/^[atc]*$/ 放置“不匹配:”+t+“”+temp 下一个 终止 临时潜艇/aa$/,“A”; 如果温度匹配/aA | aA | tt | cc/ 放置“不匹配:”+t[0..80] 如果v 其他的 放置“匹配:”+t[0..80] 除非v,否则放错 终止 终止
我用“字符”运行这个程序,通常是30个字符或更多,“目标”是一组大约100k的条目,所以不确定它是否是最佳时间。我将试着看看我是否能以任何方式修改或取消它。谢谢你给出这个简单而有力的答案!将字符按相同字符分组:['a','c','t','a','c']=>['aa','cc','t']。然后迭代这些组并执行target.replacegrp[0],lengrp。也就是说,基本的字符串操作几乎可以保证优于基于正则表达式的解决方案。@Swopnil可以轻松地进行分组,请参见修改后的答案。我使用“字符”通常为30个字符或更多,“目标”作为一组大约100k的条目运行,所以不确定它是否是最佳时间。我将试着看看我是否能以任何方式修改或取消它。谢谢你给出这个简单而有力的答案!将字符按相同字符分组:['a','c','t','a','c']=>['aa','cc','t']。然后迭代这些组并执行target.replacegrp[0],lengrp。也就是说,基本字符串操作几乎可以保证优于基于正则表达式的解决方案。@Swopnil可以轻松地进行分组,请参见修改后的答案。这是不正确的。例如,它匹配ac*。因为集合是有限的,所以肯定有一个CFG甚至正则表达式。但是没有递归/Kleene星。这是不正确的。例如,它匹配ac*。因为集合是有限的,所以肯定有一个CFG甚至正则表达式。但没有递归/克莱恩星。