Как поддержать ссылку "внутренний" выбор (()) в регулярном выражении?
Как вернуть обратную внутреннюю скобку в Regex?
Образец данных - это прейскурант продукта, показывающий разные ценовые разрывы на основе приобретенного количества. Формат - количествоLow - количествоHigh: pricePer; кратными.
Я использовал LINQPad для создания этого выражения С# 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 элемент)() Соответствует "1-4; 2;"
- Групповая коллекция (4 предмета)
- CaptureCollection (1 элемент)() Группа "5-9: 1.89"
- CaptureCollection (1 элемент)() Группа "5"
- CaptureCollection (1 элемент)() Группа "9"
- CaptureCollection (1 элемент)() Группа "1.89"
- CaptureCollection (1 элемент)() Соответствует "5-9: 1.89"
Только для справки:
- () группа скобок обнаружила результаты, на которые можно ссылаться на \1..\9 (я думаю).
- \d соответствует одной цифре. + После соответствует одной или нескольким цифрам. * после совпадений ноль или более цифр.? после говорит, что это совпадение необязательно.
- . соответствует одному символу. \. в этом случае соответствует периоду или десятичному значению.
Ответы
Ответ 1
Просто используйте \1
... \9
(или $1
... $9
в некоторых реализациях регулярных выражений), как обычно. Нумерация выполняется слева направо, в зависимости от положения открытого элемента (так что вложенная группа имеет большее число, чем группа (группы), в которую она вложена).
Ответ 2
Обратите внимание, что это ответ на комментарий доктора Зима:
"Как ни странно, оба способа, похоже, работают нормально. Я взял" Регулятор ", который, по крайней мере, показывает, как разбивается регулярное выражение. Если у него есть функция для установки реализации, я думаю, что я в бизнесе".
но мой ответ был слишком длинным для окна комментариев.
Нет, вам не нужно избегать плюса, и в этом случае дефис. Внутри класса символов следующие символы имеют особое значение: ]
, ^
и -
. Эти три символа являются единственными символами, которым может потребоваться экранирование (обратите внимание, что [
не требует экранирования!). Я могу сказать, потому что это зависит от того, где происходят эти метасимволы. ^
имеет особый смысл (как индикатор отрицания) при размещении в начале класса символов, в другом месте он не нуждается в экранировании и будет соответствовать буквальному ^
. Примеры для иллюстрации:
[^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 (хотя и не обязательно), что буквальный +
сопоставляется вместо жадного квантификатора.
Надеюсь, что это очистит.
Ответ 3
В качестве побочного примечания классы символов всегда соответствуют одному символу, и в них не применяются "нормальные" метасимволы. Таким образом, класс [-|\+]
соответствует одному из трех символов -
, |
или +
. Как вы видите, логический ИЛИ метасимвол не имеет особого значения внутри класса символов. И вам не нужно избегать символа +
внутри класса символов, поэтому это должно сделать это: [-+]
.