Skip to main content
 首页 » 编程设计

python之使用正则表达式验证用户输入

2024年09月03日35zlslch

我对正则表达式的经验非常有限,所以我希望有人能帮助我。

我正在制作一个以矩形网格作为棋盘的 Python 3 游戏。我正在尝试为用户提供一种方法,让用户以以下形式一次将多个板坐标输入到一个名为 coords 的字符串中:

(x1, y1), (x2, y2), (x3, y3), ... (xn, yn) 

我希望输出是一个名为 cells 的元组列表,格式类似:

[(x1, y1), (x2, y2), (x3, y3), ... (xn, yn)] 

所以本质上我想模仿如何用 Python 代码编写元组。

现在我正在使用:

cells = [tuple(coords[i.find('(') + 1: i.rfind(')')].split(',')) for i in coords.split()] 

它为 (1,2) (3,4) (5,6) 形式的输入生成所需的结果,输入的元组内部和元组之间没有空格。但是,这会中断不完全遵循该形式的输入,并且不会检查有效输入。对于 cells 元组中的每个 x 和 y 值,我需要验证:

  1. 类型(y 值)== 类型(x 值)== int
  2. 0 <= y 值 < game_board.height
  3. 0 <= x-value < game_board.width

理想情况下,如果用户输入多个有效坐标和一些无效坐标,有效元组将被添加到 cells 并且用户将收到类似 “The following coordinates were invalid : (x1, y1), ...”。

我知道我可以用一堆乱七八糟的循环和流量控制来完成这一切,但是有没有更 Pythonic 的方法来用正则表达式来完成这个?

编辑:拼写

请您参考如下方法:

Regex 用于测试整体结构 - 其余的在没有 regex 的情况下完成:

inp = "(3, 4), (a, 7), (-3, 3), (3, 3)" 
 
def MaybeInt(n): 
    """Returns an int if possible, else the original value.""" 
    try: 
        return int(n) 
    except: 
        return n 
 
def inX(n): 
    """True if inside X of board.""" 
    return 0<=n<5 
 
def inY(n): 
    """True if inside Y of board.""" 
    return 0<=n<5 
 
def structOk(t): 
    import re 
    return re.match(r'^\s*([^,]+,[^,]+\)\s*(?:,\s*\([^,]+,[^,]+\))*)\s*$',t) 
 
def validate(t): 
    t = t.replace(" ","") 
    if not structOk(t): 
        raise ValueError("Structually unsound - try again: "+t) 
 
    k = [ x.lstrip("(") for x in t.replace(" ","").rstrip(")").split("),")] 
    tups = [ tuple(map(MaybeInt,tu.split(","))) for tu in k] 
 
    # our "decider" for whats valid/invalid which is used to divide the tuples 
    # into our valid/invalid return list's 
    test = lambda q: all(isinstance(num,int) for num in q) and inX(q[0]) and inY(q[1]) 
 
 
    rv = [[],[]]  # prepare and append by our decider test 
    for k in tups: 
        # True == 1, False == 0 
        rv[1-test(k)].append(k) 
 
    return rv 
 
valid, invalid = validate(inp) 
 
print(valid) 
print(invalid) 

输出:

[(3, 4), (3, 3)]    # valid 
[('a', 7), (-3, 3)] # invalid 

有关正则表达式和详细说明,请参阅 https://regex101.com/r/OrHGaR/1。

简短描述:它正在寻找 ( ... , ...) 而 ... 不是 , - 您可以使用 f.e. [1234567890a-zA-Z] 而不是 [^,] 但它迟早会进入 ValueError。