Как использовать оглядку назад с группой повторного захвата - PullRequest
0 голосов
/ 19 сентября 2019

Регулярное выражение для боулинга

Я играл с регулярным выражением, чтобы сопоставить различные возможные значения в боулинге (см. Игра в боулинг https://cyber -dojo.org ).

Первоначально я написал программу на Python 3 без использования регулярных выражений, но теперь я хочу, чтобы версия регулярных выражений JSON показала, насколько проще и понятнее она может быть (если вы понимаете регулярное выражение:)

Ниже объясняется проблемано сложность, с которой я столкнулся, связана с регулярным выражением, сгруппировав 10 кадров с оценками отдельно, чтобы соответствовать бонусу.

Мне нужно посмотреть в 10-м кадре, чтобы правильно соответствовать тому, что происходит в бонусной области.

Кроме того, если бы вы могли указать на любые другие ошибки, я был бы очень признателен.

Проблема

Symbols

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

|     : frame
  • Оценка состоит из 1 или 2символы, разделенные символом кадра.
  • Есть 10 кадров.
  • После 10 кадров - это бонусные баллы, разделенные двумя символами кадра.

Пример оценкишаблон:

8/|X|-/|-4|3-|--|9/|55|23|X||-/
  • Шаблон партитуры представлен в виде строки.
  • Каждый партитура состоит из 1 удара или 2 других символов (не вкл.Рамка).
  • Оценка не может начинаться с запасного.

Пример бонусной оценки (показывает предшествующий 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)
  • Область бонуса может бытьзаполняется
    • 1 символом (если оценка 10-го кадра закончилась с запасом)
    • или 2 символами (если оценка 10-го кадра была ударом)
    • или 0 символов (если 10-й кадр не был ни тем, ни другим).
  • Бонусная оценка не может начинаться с запасной части.
  • Запасная часть не может следовать за ударом.

Я создал следующий шаблон (используя https://regex101.com, где вы можете увидеть разбивку):

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

Это соответствует символам, обозначающим бонусную зону,Я хотел бы использовать просмотр сзади, чтобы определить счет в 10-м кадре, чтобы определить, что происходит в бонусной зоне.

Редактировать

Я получаю следующееподсказка:

«Повторная группа захвата будет захватывать только последнюю итерацию. Поместите группу захвата вокруг повторяющейся группы, чтобы захватить все итерации, или используйте вместо этого группу без захвата, если вас не интересуют данные»

Однако я не могу заставить это работать.Возможность сделать это позволит мне получить доступ к оценкам во всех кадрах, особенно.10-й кадр, обозначающий бонусную зону.

Extra

Есть ли способ рассчитать оценки, используя JSON, т. е. если мы разбили шаблон регулярных выражений на их части и присвоили значениек этому подразделу в JSON?

Таким образом, для каждой сопоставляемой группы мы могли бы каким-то образом получить ее значение, чтобы вычислить сумму для всего совпадения?

1 Ответ

0 голосов
/ 20 сентября 2019

Прежде всего, я не думаю, что регулярное выражение - лучший способ решить эту проблему.Если вы ищете только последнюю группу, я бы порекомендовал что-то вроде этого:

# 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,
    ...
}
...