Python 与给定字符集的powerset中的任何内容匹配的正则表达式
我正在写一个字符串模式匹配算法,我计划用正则表达式实现它。我希望正则表达式能够匹配给定字符列表的powerset中的任何字符串 我希望正则表达式以以下方式匹配: 假设我们有一份清单 s=['a','c','t','a'] 一些匹配的字符串可能是: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
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甚至正则表达式。但没有递归/克莱恩星。