如何使用PyInputPlus的blockRegexes方法阻止单个阿拉伯数字输入并实现纯罗马数字输入验证
我来帮你梳理下当前代码的问题,然后给出能满足你需求的解决方案:
首先看你遇到的两个问题的根源:
- blockRegexes阻止了所有整数:你用的
r'([0-9]{1})'会匹配输入里的任意单个数字字符,而不是仅整个输入是单个数字。比如输入"12"里包含'1'和'2'两个单个数字,所以也会被判定为违规,这就导致所有带数字的输入都被阻止了。 - 允许罗马数字与阿拉伯数字混合输入:原
allowRegexes里的r'[I|V|X|L|C|D|M]'只要输入里出现任意一个罗马字符就会放行,完全没检查输入是否全是罗马字符,所以"M1"这种混合内容自然能通过验证。
另外还有个隐藏坑:pyip.inputNum()会强制把输入转换成数字类型,但罗马数字字符串(比如"I")和"zero"没法直接转成数字,就算正则通过了,这个函数还是会报错拒绝这些输入。
解决方案1:仅验证输入格式(不需要转数字)
如果你只需要确保输入符合格式要求,不需要得到数字类型的结果,可以改用pyip.inputStr(),同时调整正则规则:
import pyinputplus as pyip response = pyip.inputStr( prompt='Input a number, Roman numeral, or "zero": ', allowRegexes=[r'^[IVXLCDM]+$', r'^zero$'], blockRegexes=[r'^\d$'], limit=20, timeout=30 ) print(response)
这里的正则规则做了这些调整:
r'^\d$':只匹配整个输入是单个阿拉伯数字的情况,这样输入"0"-"9"会被阻止,但"123"这类多位数能正常通过。r'^[IVXLCDM]+$':要求整个输入全由罗马字符组成(可以是一个或多个,比如"I"、"XIV"都符合),混合输入会被直接拒绝。r'^zero$':只允许输入完全是"zero"的情况,避免类似"zero123"这种混合内容通过。
解决方案2:验证并转换为数字类型
如果你希望最终得到数字类型的结果(比如把"I"转成1,"zero"转成0),可以用自定义验证函数,配合roman模块来处理罗马数字转换(先通过pip install roman安装这个模块):
import pyinputplus as pyip import roman def validate_input(input_str): # 处理"zero"(不区分大小写) if input_str.lower() == 'zero': return 0 # 处理合法罗马数字 try: return roman.fromRoman(input_str.upper()) except roman.InvalidRomanNumeralError: pass # 处理阿拉伯数字:排除单个数字,允许多位数 if input_str.isdigit(): if len(input_str) == 1: raise ValueError("Single digit numbers are not allowed.") return int(input_str) # 其他情况直接抛出错误 raise ValueError("Invalid input. Please enter a multi-digit number, valid Roman numeral, or 'zero'.") response = pyip.inputCustom( validate_input, prompt='Input a number, Roman numeral, or "zero": ', limit=20, timeout=30 ) print(f"Parsed value: {response}")
这个自定义函数会逐一验证输入:
- 先检查是否是"zero"(不区分大小写),是的话返回0;
- 再尝试把输入转成罗马数字,合法的话返回对应的整数;
- 最后检查是否是阿拉伯数字,单个数字会报错,多位数则返回整数;
- 不符合以上情况的输入都会被拒绝。
内容的提问来源于stack exchange,提问作者Philip Melkowski
相关产品推荐
相关产品推荐

