Как вернуть ссылку на «внутренние» выборки (()) в регулярном выражении? - PullRequest
2 голосов
/ 09 октября 2009

Как вы ссылаетесь на внутренние скобки в Regex?

Примерные данные представляют собой прайс-лист на продукцию, показывающий различные ценовые разрывы в зависимости от приобретенного количества. Формат - количествоLow - количествоHigh: ценаPer; кратные.

Я использовал LINQPad для создания этого выражения C # Regex для разделения частей, которое показывает удобную визуализацию разделения данных Regex. В этом примере присутствуют «внутренние» скобки (выборки), создающие иерархическую структуру данных.

string mys = "1-4:2;5-9:1.89";
Regex.Matches (mys, @"((\d+)[-|\+](\d*):(\d+\.?\d*);?)").Dump();  // Graphically show

Это разбивается на (Совпадение - это все. Внутри матча есть одиночное совпадение и групповое совпадение. Внутри группового совпадения несколько одиночных совпадений.)

  • MatchCollection (2 предмета)
    • Групповая коллекция (4 предмета)
      • CaptureCollection (1 элемент) () Группа "1-4: 2;"
      • CaptureCollection (1 элемент) () Группа "1"
      • CaptureCollection (1 элемент) () Группа "4"
      • CaptureCollection (1 элемент) () Группа "2"
    • CaptureCollection (1 item) () Match "1-4; 2;"
    • Групповая коллекция (4 предмета)
      • CaptureCollection (1 элемент) () Группа "5-9: 1,89"
      • CaptureCollection (1 элемент) () Группа "5"
      • CaptureCollection (1 элемент) () Группа "9"
      • CaptureCollection (1 шт.) () Группа "1,89"
    • CaptureCollection (1 item) () Матч "5-9: 1,89"

Только для справки:

  • () Группа скобок нашла результаты, на которые может ссылаться \ 1 .. \ 9 (я думаю).
  • \ d соответствует одной цифре. Знак + соответствует одной или нескольким цифрам. * после совпадений ноль или более цифр. ? после говорит, что это совпадение необязательно.
  • . соответствует одному символу. \. соответствует периоду или десятичному числу в этом случае.

Ответы [ 3 ]

4 голосов
/ 10 октября 2009

Просто используйте \1 ... \9 (или $1 ... $9 в некоторых реализациях регулярных выражений), как обычно. Нумерация ведется слева направо, в зависимости от положения открытой пары (поэтому вложенная группа имеет большее число, чем группа (и), в которую она вложена).

3 голосов
/ 12 октября 2009

Обратите внимание, что это в ответ на комментарий д-ра Зима:

"Как ни странно, оба способа работают нормально. Я выбрал" Регулятор ", который, по крайней мере, показывает, как разбивается регулярное выражение. Если у него есть возможность установить реализацию, я думаю, что я в бизнесе."

но мой ответ был слишком длинным для поля для комментариев.

Нет, вам не нужно избегать плюса, а в данном случае дефиса. Внутри класса символов следующие символы имеют особое значение: ], ^ и -. Эти три символа являются единственными символами, которые могут * нуждаться в экранировании (обратите внимание, что [ не требует экранирования!). Я говорю может , потому что это зависит от того, где эти метасимволы встречаются. ^ имеет специальное значение (например, индикатор отрицания ) только в том случае, если он находится в начале класса символов, в другом месте он не нуждается в экранировании и будет соответствовать только буквальному значению ^. Некоторые примеры для иллюстрации:

[^a]   // special meaning: matches any character except 'a'
[a^]   // matches 'a' or '^'
[\^a]  // matches '^' or 'a'

И дефис имеет специальное значение (например, указатель диапазона ), когда ставится , а не в начале или конце класса символов. Примеры:

[a-c]  // special meaning: matches 'a', 'b' or 'c'
[ac-]  // matches 'a', 'c' or '-'
[-ac]  // matches '-', 'a' or 'c'
[a\-c] // matches 'a', '-' or 'c'

Без сомнения, некоторые реализации регулярных выражений могут отличаться от того, что я только что опубликовал, но большинство языков будут соответствовать этим правилам (по крайней мере, все языки, с которыми я работал!). И, как вы заметили, безопаснее экранирования символов внутри классов символов: это не причинит никакого вреда. Оба класса [+] и [\+] будут соответствовать литералу +. ИМХО, первое предпочтительнее, потому что я нахожу регулярное выражение со слишком многими побегами, которые трудно прочитать. Но некоторые не согласятся со мной и обнаружат, что при использовании escape (хотя и не обязательно) становится совершенно ясно, что вместо жадного квантификатора сопоставляется литерал +.

Надеюсь, что все прояснилось.

1 голос
/ 10 октября 2009

В качестве примечания, классы символов всегда соответствуют одному символу, и «нормальные» метасимволы в них не применяются. Таким образом, ваш класс [-|\+] соответствует одному из трех символов -, | или +. Как видите, метасимвол логического ИЛИ не имеет специального значения внутри класса символов. И вам не нужно экранировать символ + внутри класса символов, так что это должно сделать это: [-+].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...