根据 Python 中的逻辑关系进行此字符串模式替换的最快方法是什么?
What is the fastest way to do this string patten substitution based on the logical relations in Python?
例如,
1. str1 = 'A>1 and A>=3 and B<2 and B<=3 and B<1 ...', should be substituted to:
str1 = 'A>=3 and B<1 ...';
2. str2=['A=1 and B<=2 ...', 'A=1 and B>2 ...'], should be substituted to:
str2=['A=1 ...'], where B is skipped
A、B 可以是任意长度的合法 python 标识符。 str1 和 str2 中都有未知数量的逻辑操作数。
通常的正则表达式搜索方法很难解决这个问题。有什么破解方法吗?
编辑:
为简单起见,我们只考虑'and'操作,所有操作数按字符串排序,即
'A<x and A<y and A<z' will always appear next to each other
from itertools import groupby
import re
str1 = "A>1 and A>3 and B<2 and B<3"
comparisions = [s.strip() for s in str1.split("and")]
operands = [re.search(r'(\w+)([<>][=]?)(\w+)',c).groups() for c in comparisions]#
tot={}#total results
for k,g in groupby(operands,lambda x:x[0]):#group by variable1
for arg in g:#arg is the match with list [var1,compareitem,var2]
if k not in tot:tot[k] = {}
if arg[1] in tot[k]:
print("do the overwrite handling!")
tot[k][arg[1]] = arg[2]
#sort tot
sortedkeys = sorted(tot, key=lambda x: x[0])
resub_str = " and ".join([comp+"".join([k+tot[comp][k] for k in tot[comp]]) for comp in sortedkeys])
print(resub_str)
输出:
do the overwrite handling!
do the overwrite handling!
A>3 and B<3
想法:
- 拆分条件语句数组中的字符串。
这样我们就有了
[A>1,A>3,B<2,B<3]
等等。
- 使用匹配 [VARIABLE1][COMPARE_ITEM][VARIABLE2] 的模式搜索每个条件,其中
COMPARE_ITEM
是 <,>,<=,>=
之一
- 我们现在按
VARIABLE1
分组并搜索结果(如果我们已经有 VARIABLE1
的条件)。如果我们有 - 覆盖。如果没有,就插入它。
- 按
VARIABLE1
对数组进行排序,并使用 " and "
连接条件部分
您可以改进代码,不仅要搜索 Var1,还要搜索 variable2 并为每个使用的变量创建一个引用。
(因此 A<B and A< 4
的结果与 B>A and 4>A
相同)。
例如,
1. str1 = 'A>1 and A>=3 and B<2 and B<=3 and B<1 ...', should be substituted to:
str1 = 'A>=3 and B<1 ...';
2. str2=['A=1 and B<=2 ...', 'A=1 and B>2 ...'], should be substituted to:
str2=['A=1 ...'], where B is skipped
A、B 可以是任意长度的合法 python 标识符。 str1 和 str2 中都有未知数量的逻辑操作数。
通常的正则表达式搜索方法很难解决这个问题。有什么破解方法吗?
编辑:
为简单起见,我们只考虑'and'操作,所有操作数按字符串排序,即
'A<x and A<y and A<z' will always appear next to each other
from itertools import groupby
import re
str1 = "A>1 and A>3 and B<2 and B<3"
comparisions = [s.strip() for s in str1.split("and")]
operands = [re.search(r'(\w+)([<>][=]?)(\w+)',c).groups() for c in comparisions]#
tot={}#total results
for k,g in groupby(operands,lambda x:x[0]):#group by variable1
for arg in g:#arg is the match with list [var1,compareitem,var2]
if k not in tot:tot[k] = {}
if arg[1] in tot[k]:
print("do the overwrite handling!")
tot[k][arg[1]] = arg[2]
#sort tot
sortedkeys = sorted(tot, key=lambda x: x[0])
resub_str = " and ".join([comp+"".join([k+tot[comp][k] for k in tot[comp]]) for comp in sortedkeys])
print(resub_str)
输出:
do the overwrite handling!
do the overwrite handling!
A>3 and B<3
想法:
- 拆分条件语句数组中的字符串。
这样我们就有了
[A>1,A>3,B<2,B<3]
等等。 - 使用匹配 [VARIABLE1][COMPARE_ITEM][VARIABLE2] 的模式搜索每个条件,其中
COMPARE_ITEM
是<,>,<=,>=
之一
- 我们现在按
VARIABLE1
分组并搜索结果(如果我们已经有VARIABLE1
的条件)。如果我们有 - 覆盖。如果没有,就插入它。 - 按
VARIABLE1
对数组进行排序,并使用" and "
连接条件部分
您可以改进代码,不仅要搜索 Var1,还要搜索 variable2 并为每个使用的变量创建一个引用。
(因此 A<B and A< 4
的结果与 B>A and 4>A
相同)。