Как сопоставить экранированные символы в группах в Java RegEx - PullRequest
0 голосов
/ 25 мая 2019

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

15.00|GR,LQ,MD "Uber"

где сумма может быть с десятичной дробью, равной двум, или с целым числом. Мне нужно собрать всю информацию о группах. «Uber» является необязательным описанием.

Вот что я пробовал ..

Pattern.compile("ˆ([\\d]+(\\.[\\d]{2})?\\|([A-Z]{2}){1})(,[A-Z]{2})*\\s(\\\".+\\\")?$");

Я ожидаю получить число, двухсимвольных пользователей и, возможно, описание тоже.

Ответы [ 3 ]

2 голосов
/ 25 мая 2019

Есть 2 основных вопроса.

  • Символ ˆ представляет собой акцентирующий круговой знак вместо ^ каретки.
  • Вы не включаете квадратные скобки в регулярное выражение.

Возможное решение может быть таким:

Pattern.compile("^\\[(?<number>[\\d]+(?>\\.[\\d]{2})?)\\|(?<codes>(?>[A-Z]{2},?)+)(?>\\s\\\"(?<comment>.+)\\\")?\\]$");

Это решение также имеет именованные группы захвата, что позволяет лучше указать, из какой группы вы хотите получить значение. https://regex101.com/r/HEboNf/2

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

2 голосов
/ 25 мая 2019

Ваше регулярное выражение проанализировано:

"ˆ([\\d]+(\\.[\\d]{2})?\\|([A-Z]{2}){1})(,[A-Z]{2})*\\s(\\\".+\\\")?$"

Во-первых, давайте отвлечемся от строкового литерала Java в фактическую строку регулярного выражения:

ˆ([\d]+(\.[\d]{2})?\|([A-Z]{2}){1})(,[A-Z]{2})*\s(\".+\")?$

Теперь давайте разделим это на части:

ˆ                  Incorrect character 'ˆ', should be '^'
                   Match start of input, but your input starts with '['
(                  
  [\d]+            The '[]' is superfluous, use '\d+'
  (\.[\d]{2})?     Don't capture this, use '(?:X)?'
  \|
  ([A-Z]{2}){1}    The '{1}` is superfluous, and don't capture just this
)                  You're capturing too much. Move back to before '\|'
(,[A-Z]{2})*       Will only capture last ',XX'.
                   Use a capture group around all the letters, then split that on ','
\s
(\".+\")?          No need to escape '"', and only capture the content
$                  Match end of input, but your input ends with ']'

Итак, вычистить это будет:

^\[
(
  \d+
  (?:\.[\d]{2})?
)
\|
(
  [A-Z]{2}
  (?:,[A-Z]{2})*
)
\s
(?:"(.+)")?
\]$

Соединены вместе:

^\[(\d+(?:\.[\d]{2})?)\|([A-Z]{2}(?:,[A-Z]{2})*)\s(?:"(.+)")?\]$

С вводом [15.00|GR,LQ,MD "Uber"], который будет захватывать:

  1. 15.00 - полный номер
  2. GR,LQ,MD - Используйте split(","), чтобы получить массив { "GR", "LQ", "MD" }
  3. Uber - просто текст без кавычек

См. Демо на regex101.com.

2 голосов
/ 25 мая 2019

Первый символ - ˆ, а не ^. Кроме того, вы должны изменить свою первую группу на ([\d]+(\.[\d]{2})?), чтобы получить только 15.00, а не 15.00|GR.

Полный пример будет выглядеть так:

Pattern.compile("^([\\d]+(\\.[\\d]{2})?)\\|(([A-Z]{2})(,[A-Z]{2})*)\\s(\".+\")?$");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...