python - 如何在python中排除字符组

标签 python regex python-3.x

我想编写一个脚本,返回 1 的幂的数字。用户的输入是二次和正常数字。我想要的描述如下:

input = "+2**5+3+4**8-7"
Output = "3,-7"

我尝试了正则表达式 re.findall(r"[+-]?[0-9]+[^[*][*][2]]", input) 但它没有工作 提前致谢:)

最佳答案

您需要一个否定环视断言,并添加边界 anchor :

r'(?<!\*\*)-?\b\d+\b(?!\*\*)'

(?<!...)语法仅在其前面的文本与模式不匹配的位置匹配。同样,(?!...)语法对后面 文本的作用相同。它们一起确保您只匹配不是指数的数字(遵循 ** )并且没有指数(遵循 ** )。

\b边界 anchor 仅在字符串的开头或结尾匹配,并且任何地方有一个单词字符后跟一个非单词字符,反之亦然(所以在 \w\W\W\w 之间,其中 \w 愉快地包含数字但不算术字符):

>>> import re
>>> input = "+2**5+3+4**8-7"
>>> re.findall(r'(?<!\*\*)-?\b\d+\b(?!\*\*)', input)
['3', '-7']

请注意,我使用了 \d匹配数字,并删除了 +从模式中,因为你不希望它出现在你的预期输出中。

您可以使用 online regex101 demo 中的表达式;例如您可以尝试使用大于 10 的数字并使用单个 *乘法。

如果你必须支持负指数,那么上面的 ...**-42 是不够的有42没有 ** 的匹配在数字之前。在那种情况下,在 -? 之前进行额外的负面回溯。不允许 **-需要:

r'(?<!\*\*)-?(?<!\*\*-)\b\d+\b(?!\*\*)'

(感谢 Casimir eg Hippolyte 指出了我的这一点并提出了解决方案)。

但是,在这一点上,我建议您切换到仅将表达式解析为 abstract syntax tree然后遍历树以提取不属于指数的操作数:

import ast

class NumberExtractor(ast.NodeVisitor):
    def __init__(self):
        self.reset()

    def reset(self):
        self.numbers = []

    def _handle_number(self, node):
        if isinstance(node, ast.Constant):
            if isinstance(node.value, (int, float, complex)):
                return node.value
        elif isinstance(node, ast.Num):
            return node.n

    def visit_UnaryOp(self, node):
        if isinstance(node.op, (ast.UAdd, ast.USub)):
            operand = self._handle_number(node.operand)
            if operand is None:
                return
            elif isinstance(node.op, UAdd):
                self.numbers.append(+operand)
            else:
                self.numbers.add(-operand)

    def visit_Constant(self, node):
        if isinstance(node.value, (int, float, complex)):
            self.numbers.append(node.value)

    def visit_Num(self, node):
        self.numbers.append(node.n)

    def visit_BinOp(self, node):
        if isinstance(node.op, ast.Pow):
            return  # ignore exponentiation
        self.generic_visit(node)  # process the rest

def extract(expression):
    try:
        tree = ast.parse(expression, mode='eval')
    except SyntaxError:
        return []
    extractor = NumberExtractor()
    extractor.visit(tree)
    return extractor.numbers

这只提取数字;减法不会产生负数:

>>> input = "+2**5+3+4**8-7"
>>> extract(input)
[3, 7]

此外,它可以处理任意数量的空格,以及比正则表达式处理的复杂得多的表达式:

>>> extract("(10 + 15) * 41 ** (11 + 19 * 17) - 42")
[10, 15, 42]

关于python - 如何在python中排除字符组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58048173/

相关文章:

python - 在 Jupyter Notebook 中运行 Python 脚本,并传递参数

python - 使用 Networkx 计算顶点所属的最短路径数的更快方法

javascript - 匹配简单 URL 的正则表达式无法正常工作

python - 如何在巨大数据帧的每一行中找到前 n 个值的列索引

python - 如何将两个列表与第三个列表进行比较,如果存在匹配,则将它们分组到Python中的嵌套列表中?

javascript - 使用 JavaScript 将文本添加到 url 的开头

python - 从大字典中弹出 N 项的最快方法

python - 使用 for 循环查找句子中的单词及其索引位置

python - 有没有办法让python程序到 "refresh the sd drive connection"

python - 而不是重复一个循环多次 'merge' 变成一个