Регулярное выражение составного кубика в стиле d и d

Я работаю над проектом на Java, в котором пользователь вводит выражение для игры в кости. Я использую регулярное выражение для проверки ввода, чтобы убедиться, что это действительное выражение кубика в стиле D&D. Я имею в виду такие выражения:

d20
2D12+ 4 - 2
12d4-2d6+7 + d8
7 + 1d12

Все будет в силе. Тогда как такие выражения:

-2d6+4
-d8 - 5
12
2d0 + 5
1d6 + 0d2 - 1
0d6

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

^((((0+\d+|[1-9]\d*|)(d|D)(0+\d+|[1-9]\d*))|(\d+))((\ *(\+|\-)\ *)(?=(((0+\d+|[1-9]\d*|)(d|D)(0+\d+|[1-9]\d*))|(\d+))))?)+$

Однако это регулярное выражение по-прежнему соответствует таким выражениям, как «0d6». Мы будем очень благодарны за любую помощь в создании регулярного выражения для этого.

Мне это не кажется и не похоже, что регулярное выражение - это путь сюда. Напишите небольшой набор кубиков и связанных классов синтаксического анализа, и вам будет намного легче понять свой код, когда вы вернетесь к нему, чтобы поддерживать или расширять его.

daniu 10.09.2018 08:35

Попробуйте ^(?!\d+$)(?:[1-9]\d*)?[dD]?[1-9]\d*(?:\s*[-+\/*]\s*(?:[1-9]\‌​d*)?[dD]?[1-9]\d*)*$‌.

Wiktor Stribiżew 10.09.2018 08:41

Согласитесь с @daniu - это похоже на случай DSL, а не регулярное выражение.

Mike Harris 10.09.2018 21:35
2
3
279
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

^(?!\d+$)(([1-9]\d*)?[Dd]?[1-9]\d*( ?[+-] ?)?)+(?<![+-] ?)$

Объяснение:

^              | Enforce beginning of string
(?!\\d+$)      | If 1+ digits at end of string are matched, don't match the following:
(              | Begin group
  ([1-9]\\d*)? |   Optionally match numbers not starting with 0 of any length
  [Dd]?        |   Optionally match either "D" or "d"
  [1-9]\\d*    |   Match numbers not starting with 0 of any length
  ( ?[+-] ?)?  |   Optionally match a "+" or "-" optionally surrounded by spaces
)+             | End group; one or more of these should exist
(?<![+-] ?)    | A "+" or "-" with an optional space shouldn't precede the end
$              | Enforce end of string

Попробуйте здесь

Пример кода:

String userInput = "12d4-2d6+7 + d8";

Pattern p = Pattern.compile("^(?!\\d+$)(([1-9]\\d*)?[Dd]?[1-9]\\d*( ?[+-] ?)?)+$");
Matcher m = p.matcher(userInput);
boolean b = m.matches();

System.out.println(b); // true

Именно то, что мне нужно! Подробное объяснение особенно полезно. Очень признателен!

Surram 11.09.2018 07:32

@Surram Обратите внимание, что это регулярное выражение неправильно соответствует "7d +".

daniu 11.09.2018 09:28

@daniu Я не понимаю, как ты это понял. Я проверил это значение, и оно не совпадает.

Adam 11.09.2018 09:51

@ Адам Ты прав, извини, я ошибся. Ошибочный матч - «7d4 +».

daniu 11.09.2018 10:01

Обновил регулярное выражение, чтобы устранить проблему.

Adam 11.09.2018 20:07

Другие вопросы по теме