Что такое группа без захвата?Что делает (? :)? - PullRequest
1564 голосов
/ 18 августа 2010

Как используется ?: и для чего он нужен?

Ответы [ 15 ]

5 голосов
/ 02 января 2018

Я не могу комментировать верхние ответы, чтобы сказать это: я хотел бы добавить явное замечание, которое подразумевается только в верхних ответах:

Группа без захвата (?...) не удаляет каких-либо символов из исходного полного соответствия, это только визуально реорганизует регулярное выражение для программиста.

Чтобы получить доступ к определенной части регулярного выражения без определенных посторонних символов, вам всегда нужно будет использовать .group(<index>)

5 голосов
/ 15 июля 2017

Одна интересная вещь, с которой я столкнулся, это то, что вы можете иметь группу захвата внутри группы без захвата.Обратите внимание на регулярное выражение для соответствия веб-URL:

var parse_url_regex = /^(?:([A-Za-z]+):)(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

Строка URL-адреса ввода:

var url = "http://www.ora.com:80/goodparts?q#fragment";

Первая группа в моем регулярном выражении (?:([A-Za-z]+):) - это группа без захвата, которая соответствуетсхема протокола и двоеточие : символ, то есть http:, но когда я работал под кодом ниже, я увидел, что первый индекс возвращаемого массива содержал строку http, когда я думал, что http и двоеточие : оба не будут сообщены, поскольку они находятся в группе без захвата.

console.debug(parse_url_regex.exec(url));

enter image description here

Я подумал, что первая группа (?:([A-Za-z]+):)группа без захвата, почему она возвращает строку http в выходном массиве.

Так что, если вы заметили, что внутри группы без захвата есть вложенная группа ([A-Za-z]+).Эта вложенная группа ([A-Za-z]+) является группой захвата (не имеющей ?: в начале) внутри самой группы захвата (?:([A-Za-z]+):).Вот почему текст http все еще захватывается, но символ двоеточия :, который находится внутри группы без захвата, но вне группы захвата, не отображается в массиве вывода.

2 голосов
/ 23 мая 2017

Я думаю, я бы дал вам ответ, Не используйте переменные захвата, не проверив, что совпадение прошло успешно.

Переменные захвата, $ 1 и т. Д., Недействительны, если не найдено совпадение, и они также не очищены.

#!/usr/bin/perl  
use warnings;
use strict;   
$_ = "bronto saurus burger";
if (/(?:bronto)? saurus (steak|burger)/)
{
    print "Fred wants a  $1";
}
else
{
    print "Fred dont wants a $1 $2";
}

В приведенном выше примере, чтобы избежать захвата бронто в $ 1, используется (? :). Если шаблон соответствует, то $ 1 фиксируется как следующий сгруппированный шаблон. Итак, вывод будет таким, как показано ниже:

Fred wants a burger

Полезно, если вы не хотите сохранять совпадения.

1 голос
/ 07 января 2019

Это чрезвычайно просто, мы можем понять на примере простой даты, предположим, если дата упоминается как 1 января 2019 года или 2 мая 2019 года или любая другая дата, и мы просто хотим преобразовать ее в дд / мм / гггг * Для формата 1002 * нам не понадобится название месяца, то есть январь или февраль, поэтому для захвата числовой части, но не суффикса (необязательно), вы можете использовать группу без захвата.

так что регулярное выражение будет,

([0-9]+)(?:January|February)?

Это так просто.

1 голос
/ 07 мая 2018

Откройте Google Chrome devTools, а затем вкладку «Консоль» и введите:

"Peace".match(/(\w)(\w)(\w)/)

Запустите его, и вы увидите:

["Pea", "P", "e", "a", index: 0, input: "Peace", groups: undefined]

Механизм JavaScript RegExp захватывает тригруппы, позиции с индексами 1,2,3.Теперь используйте метку без захвата, чтобы увидеть результат.

"Peace".match(/(?:\w)(\w)(\w)/)

Результат:

["Pea", "e", "a", index: 0, input: "Peace", groups: undefined]

Это очевидно, что не является группой захвата.

...