【问题标题】:Manipulating substrings found to replace [duplicate]操作发现替换的子字符串[重复]
【发布时间】:2017-09-10 22:23:42
【问题描述】:

我希望替换取决于找到的内容。 IE。我所追求的一个例子可能如下

def f(x):
    return str(int(x) + 1)

print(re.sub(r"(\d)", f(r"\1"), "123"))

#print 234

但是,这当然行不通。是否有某种方式可以做我想做的事情,而不必跟踪找到的字符串的位置/长度,然后在下一行替换它? IE。我正在寻找一种一次性完成此操作的方法。


请注意,我正在处理的实际示例并不那么简单。我正在制作一个解释数学计算字符串输入的函数。

例如。 “2 + 4 * 6 / 3”

这个想法是函数将“4 * 6”替换为 24,然后将“24 / 3”替换为 8,最后将“2 + 8”替换为 10。它将搜索合适的对并使用 BIDMAS正则表达式。

【问题讨论】:

  • 正则表达式替换可以是一个函数:stackoverflow.com/questions/45620436/…,但您的评估者可能会因括号和/或运算符优先级而窒息。
  • @Rightleg 是的,看起来像,但不像原来的问题那么简单。如果是你,谢谢你的支持:),如果不是,谢谢你的支持。
  • @Jean-FrançoisFabre 是的,是我 ^^ 嗯,我目前(终于!)正在学习 re,我不知道这种可能性,所以...
  • @Rightleg 这不是很有名,但超级强大。

标签: python regex replace


【解决方案1】:

也许这很简单,但您可以通过先在乘法上应用正则表达式,然后在加法运算符上应用替换函数来构建一些简单的求值器:

import re

s = "4 + 6 * 7"

def replfunc(m):
    a = int(m.group(1))
    b = int(m.group(3))
    op = m.group(2)
    if op=="*":
        return str(a*b)
    elif op=="+":
        return str(a+b)

for op in "*+":
    s = re.sub("(\d+)\s*({})\s*(\d+)".format(re.escape(op)),replfunc,s)

这里,正则表达式尝试匹配“数字运算符号”(中间有可选空格)并在匹配时调用替换函数。

替换函数动作一致,转换为整数,执行相关操作,返回要替换的字符串。

当然,这不是为处理带括号的表达式而设计的,并且永远不会,请考虑使用第三方评估器,例如 simpleeval(在 pypi 中搜索会得到几十个结果)

【讨论】:

    【解决方案2】:

    我知道这不是您想要的方式,但您是否考虑过使用eval() 函数?

    >>> statement = input("Expression: ")
    3 + 4 * (5 + 2)
    >>> eval(statement)
    31
    

    这当然比使用 RegEx 更容易。

    有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。 - 杰米扎温斯基

    【讨论】:

    • 是的,我考虑过eval(),但这是用户输入。
    • 试试eval("__import__('os').system('clear')", {})eval("__import__('os').system('clear')", {})。用户可以将代码注入您的系统。不,不要使用eval
    • 只要您清理数据,eval 就完全没问题了。
    • 例如 a = input("Calculation: ") 然后 if re.match(r"[^\d+\-*/^()]", a): print("Invalid!") else: print(eval(a)) 这将满足您的需求。
    猜你喜欢
    • 2014-11-05
    • 2022-01-07
    • 2013-05-09
    • 2017-07-02
    • 2013-05-18
    • 2018-01-11
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多