Python如何将含True/False/括号的字符串转换为布尔值
Hey there! I get what you're trying to do—convert those boolean expression strings into actual True/False results. You're totally right that bool() won't work here, since it just checks if the string itself is non-empty instead of evaluating the logical operations inside. Let's walk through a few practical approaches, from the quickest to the most secure:
eval() Python's built-in eval() function can directly execute the expression in your string. Since your examples use Python's boolean bitwise operators (& for AND, | for OR), which work exactly as expected with True/False (since True maps to 1 and False to 0), this works seamlessly:
# Test your first expression expr1 = "(True & False) | True" result1 = eval(expr1) print(result1) # Output: True # Test your second expression expr2 = "((False | False) & (True | False)) & (False | True)" result2 = eval(expr2) print(result2) # Output: False
Note: The big caveat here is security. eval() will run any valid Python code passed to it. If this string comes from an untrusted source (like user input), malicious code could be executed—so only use this if you're 100% sure the input is safe.
ast Module To avoid the security risks of eval(), you can use Python's ast (Abstract Syntax Tree) module to parse and validate the expression first, ensuring it only contains boolean values and allowed operators before evaluating it. Here's how:
import ast def safe_evaluate_bool_expr(expr): # Parse the expression into an AST tree = ast.parse(expr, mode='eval') # Validate the AST to only allow safe nodes allowed_nodes = (ast.Expression, ast.BoolOp, ast.NameConstant, ast.BitAnd, ast.BitOr) for node in ast.walk(tree): if not isinstance(node, allowed_nodes): raise ValueError("Invalid expression: Only boolean values and &/| operators are permitted") # Compile and evaluate the validated expression compiled_expr = compile(tree, filename='', mode='eval') return eval(compiled_expr) # Test it out print(safe_evaluate_bool_expr(expr1)) # True print(safe_evaluate_bool_expr(expr2)) # False
This method restricts the expression to only boolean logic operations, so even if someone tries to inject malicious code, it'll throw an error instead of executing it.
If you want to understand how expression evaluation works under the hood, you can implement a simple tokenizer and evaluator using a stack to handle parentheses and operator precedence (& has higher priority than |). Here's a simplified example:
def tokenize_expression(expr): # Split the input string into meaningful tokens tokens = [] current_token = '' for char in expr: if char in '()&|': if current_token: tokens.append(current_token.strip()) current_token = '' tokens.append(char) else: current_token += char if current_token: tokens.append(current_token.strip()) return tokens def evaluate_tokenized_expr(tokens): stack = [] for token in tokens: if token == ')': # Calculate the result inside the parentheses sub_expr = [] while stack[-1] != '(': sub_expr.append(stack.pop()) stack.pop() # Remove the opening '(' # First evaluate all & operations (higher priority) temp = [] i = 0 while i < len(sub_expr): if sub_expr[i] == '&': a = temp.pop() b = sub_expr[i+1] temp.append(str(eval(f"{a} & {b}"))) i += 2 else: temp.append(sub_expr[i]) i += 1 # Then evaluate all | operations result = temp[0] for i in range(1, len(temp), 2): result = str(eval(f"{result} | {temp[i+1]}")) stack.append(result) else: stack.append(token) # Evaluate remaining operations outside parentheses temp = [] i = 0 while i < len(stack): if stack[i] == '&': a = temp.pop() b = stack[i+1] temp.append(str(eval(f"{a} & {b}"))) i += 2 else: temp.append(stack[i]) i += 1 result = temp[0] for i in range(1, len(temp), 2): result = str(eval(f"{result} | {temp[i+1]}")) return result == 'True' # Test with your expression tokens = tokenize_expression(expr2) print(evaluate_tokenized_expr(tokens)) # False
This is a basic implementation—you could expand it to handle more edge cases, but it's great for learning how expression parsers work.
内容的提问来源于stack exchange,提问作者Jeremie

