首页 > 解决方案 > 如何使用具有重复捕获组的后视功能

问题描述

保龄球得分的正则表达式

我一直在使用正则表达式来匹配可能的各种保龄球得分(请参阅保龄球比赛https://cyber-dojo.org)。

我最初在 Python 3 中编写程序时没有使用正则表达式,但现在我想要一个 JSON 正则表达式版本来展示它可以变得多么简单和清晰(一旦你理解了正则表达式 :)

下面解释了这个问题,但我遇到的困难在于正则表达式,将 10 帧与分数分开分组以匹配奖金。

我需要查看第 10 帧以正确匹配奖励区域中的内容。

另外,如果您能指出任何其他错误,我将不胜感激。

问题

Symbols

X     : Strike
/     : Spare
-     : Miss
[0-9] : digit

|     : frame

得分模式示例:

8/|X|-/|-4|3-|--|9/|55|23|X||-/

奖励分数示例(显示前 10 帧):

    |7-||        # (no bonus ball
    |23||        # (no bonus ball)
    |-/||2       # (1 bonus ball as Spare last in 10th frame)
    |X||X-       # (2 bonus balls as Strike in 10th frame)
    |X||-/       # (2 bonus balls as Strike in 10th frame)
    |X||7/       # (2 bonus balls as Strike in 10th frame)
    |X||XX       # (2 bonus balls as Strike in 10th frame)

我创建了以下模式(使用https://regex101.com,您可以在其中查看细分):

^(([X\d\-]((?<!X)[\/\-\d]|(?<=X)))\|){10}\|

这与表示奖励区域的符号相匹配。我想使用后视来确定第 10 帧中的分数,以确定奖励区域中发生的情况。

编辑

我得到的是以下提示:

“重复捕获组将仅捕获最后一次迭代。如果您对数据不感兴趣,请在重复组周围放置一个捕获组以捕获所有迭代或使用非捕获组代替”

但是,我无法让它发挥作用。能够做到这一点将使我能够访问所有帧中的分数,尤其是。第 10 帧表示奖励区域。

额外的

有没有办法使用 JSON 计算分数,即如果我们将正则表达式模式分解为它们的子部分并在 JSON 中为该子部分分配一个值?

这样对于每个匹配的组,我们可以以某种方式得出它的值,以便计算整个匹配的总数?

标签: jsonregexpython-3.6

解决方案


首先,我不认为正则表达式是解决这个问题的最好方法。如果您只寻找最后一组,我会推荐这样的东西:

# assume str is the score string
split_str = str.split('||')[-1]

这比任何正则表达式都更具可读性。如果您希望每个分数分组还有其他方法可以拆分它,例如使用这个简单的正则表达式:

re.split('\|{1,2}', str)

这将为您提供所有分数的数组。

现在,如果你真的想用正则表达式解决这个问题,我认为没有理由为此使用后视。(X|[\d\-\/]{1,2})通过添加到您的正则表达式的末尾,我能够获得奖金组。你可以在这里玩弄它。

至于您的奖金问题,您不能使用 JSON 将分数相加。JSON 是一种存储或传输数据的方式。但是,您可以轻松地以 JSON 格式存储从分数字符串中获得的任何信息。

但是,将这些分数字符串相加需要对符号进行一些转换(例如 X -> 10),您可以将这些转换存储在 JSON 中。这看起来很像 Python 字典:

{
    "X": 10,
    "-": 0,
    ...
}

推荐阅读