Позвольте мне попытаться объяснить это на примере.
Рассмотрим следующий текст:
http://stackoverflow.com/
https://stackoverflow.com/questions/tagged/regex
Теперь, если я применю приведенное ниже регулярное выражение к нему ...
(https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?
... Я бы получил следующий результат:
Match "http://stackoverflow.com/"
Group 1: "http"
Group 2: "stackoverflow.com"
Group 3: "/"
Match "https://stackoverflow.com/questions/tagged/regex"
Group 1: "https"
Group 2: "stackoverflow.com"
Group 3: "/questions/tagged/regex"
Но мне не важен протокол - мне просто нужен хост и путь URL.Итак, я изменяю регулярное выражение для включения группы без захвата (?:)
.
(?:https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?
Теперь мой результат выглядит следующим образом:
Match "http://stackoverflow.com/"
Group 1: "stackoverflow.com"
Group 2: "/"
Match "https://stackoverflow.com/questions/tagged/regex"
Group 1: "stackoverflow.com"
Group 2: "/questions/tagged/regex"
Видите?Первая группа не была захвачена.Синтаксический анализатор использует его для сопоставления с текстом, но игнорирует его позже, в конечном результате.
РЕДАКТИРОВАТЬ:
По запросу позвольте мне попытаться объяснить группы тоже.
Ну, группы служат многим целям.Они могут помочь вам извлечь точную информацию из большего совпадения (которое также может быть названо), они позволяют вам сопоставить предыдущую сопоставленную группу и могут быть использованы для замены.Давайте попробуем несколько примеров, ладно?
Хорошо, представьте, что у вас есть какой-то XML или HTML (учтите, что регулярное выражение может быть не лучшим инструментом для работы , но это приятноВ качестве примера).Вы хотите разобрать теги, чтобы вы могли сделать что-то вроде этого (я добавил пробелы, чтобы было легче понять):
\<(?<TAG>.+?)\> [^<]*? \</\k<TAG>\>
or
\<(.+?)\> [^<]*? \</\1\>
У первого регулярного выражения есть именованная группа (TAG), а у второгоодин использует общую группу.Оба регулярных выражения делают одно и то же: они используют значение из первой группы (имя тега), чтобы соответствовать закрывающему тегу.Разница в том, что первый использует имя для соответствия значению, а второй использует групповой индекс (который начинается с 1).
Давайте сейчас попробуем некоторые подстановки.Рассмотрим следующий текст:
Lorem ipsum dolor sit amet consectetuer feugiat fames malesuada pretium egestas.
Теперь давайте воспользуемся этим немым регулярным выражением над ним:
\b(\S)(\S)(\S)(\S*)\b
Это регулярное выражение сопоставляет слова, содержащие не менее 3 символов, и использует группы для разделения первоготри буквы.В результате получается:
Match "Lorem"
Group 1: "L"
Group 2: "o"
Group 3: "r"
Group 4: "em"
Match "ipsum"
Group 1: "i"
Group 2: "p"
Group 3: "s"
Group 4: "um"
...
Match "consectetuer"
Group 1: "c"
Group 2: "o"
Group 3: "n"
Group 4: "sectetuer"
...
Итак, если мы применяем строку подстановки:
$1_$3$2_$4
... поверх нее, мы пытаемся использовать первую группу, добавив подчеркивание, используйте третью группу, затем вторую группу, добавьте еще одно подчеркивание, а затем четвертую группу.Результирующая строка будет похожа на приведенную ниже.
L_ro_em i_sp_um d_lo_or s_ti_ a_em_t c_no_sectetuer f_ue_giat f_ma_es m_la_esuada p_er_tium e_eg_stas.
Вы также можете использовать именованные группы для подстановок, используя ${name}
.
Чтобы поиграть с регулярными выражениями, я рекомендую http://regex101.com/,, который предлагает большое количество деталей о том, как работает регулярное выражение;он также предлагает на выбор несколько двигателей регулярных выражений.