Группы ( ) и (?: )

  • Автор темы Автор темы Dziglo
  • Дата начала Дата начала
Статус
Закрыто для дальнейших ответов.

Dziglo

Участник
Топикстартер
Сообщения
226
Реакции
1
Добрый день. Возник вопрос по регулярным выражениям.
В одном из учебников написано:
( )
Простая группа с захватом.
(?: )
Группа без захвата. То же самое, но заключённое в скобках выражение не добавляется к списку захваченных фрагментов. Например, если требуется найти или «здравствуйте», или «здрасте», но не важно, какое именно приветствие найдено, можно воспользоваться выражением здра(?:сте|вствуйте).

Помещаем в InDesign текст. Например, такой:

Человек, пятница, здравствуйте небо! Зеленый — велосипед. здрасте до свидания, здравствовать

Ищу
здра(сте|вствуйте)
Находит и здрасте, и здравствуйте.

Ищу
здра(?:сте|вствуйте)
Находит и здрасте, и здравствуйте.
—————————
Чем отличаются эти операторы? Как я понимаю, во втором случае он должен был найти два раза «здра», но никак не «здравствуйте» и «здрасте».
 
В поле "заменить" вбейте $1, произведите замену и посмотрите разницу.
 
  • Спасибо
Реакции: Dziglo
@Eugenyus, так чуть понятнее, только не ясно как на практике это различие использовать.
 
ну для того чтобы сократить количество заменяемых выражений, потому как их может быть не больше 9. для экономии, так сказать, $ наверное ))
 
  • Спасибо
Реакции: NNN5 и Dziglo
@azz, пример такой экономии не могли бы привести? Если не затруднит. )
 
только предположение ) да и зачем оно вам?
Группировка без обратной связи
Если группа используется только для группировки и её результат в дальнейшем не потребуется, то можно использовать группировку вида (?:шаблон). Под результат такой группировки не выделяется отдельная область памяти и, соответственно, ей не назначается номер. Это положительно влияет на скорость выполнения выражения, но понижает удобочитаемость.
 
  • Спасибо
Реакции: Dziglo
@azz, спасибо )
изучаю регулярку. Авось пригодится.)
 
Ищу
здра(?:сте|вствуйте)
Находит и здрасте, и здравствуйте.

Как я понимаю... он должен был найти два раза «здра», но никак не «здравствуйте» и «здрасте».

Это Вы перепутали с оператором (?=сте|вствуйте) - вот тут он действительно будет искать "здра".
 
  • Спасибо
Реакции: Dziglo
@azz, пример такой экономии не могли бы привести? Если не затруднит. )
Пример жуткий. Но как попросили, так и привёл.

Код:
\b([^][\0-\x20()&<>@,;:\\".\x80-\xff](?:[^][\0-\x20()&<>@,;:\\"\x80-\xff]*?[^][\0-\x20()<>@,;:\\".\x80-\xff])*)@((?:(?:(?:[a-zA-Z0-9](?:[-a-zA-Z0-9]*[-a-zA-Z0-9])?)\.)*(?:[a-zA-Z](?:[-a-zA-Z0-9]*[a-zA-Z])?)))\b

Эта жуть всего-то ищет электронные адреса, подходящие по синтаксису RFC822 & RFC1738 за исключением - ip-адреса, как имя сервера недопустимы, хоть и разрешаются в стандарте.
При этом в $1 хранится логин, а в $2 сервер.

*Я не маньяк, это регулярное выражение составил лет десять назад, когда изучал regexp ))

Более приземленный пример. Время через двоеточие $1 - час, $2 - минута.
Код:
\b((?:[01]\d|2[0-3])):(\d{2})\b
 
Последнее редактирование:
  • Спасибо
Реакции: Dziglo
В первой половине приняты меры, чтобы ограничиться 0-23 часами, но почему тогда минуты не проверяются? В данный момент поймает и 99 минут.
кусочек ((?: ... )) - непонятен - захватить незахватываемое? Лучше будет так:
Код:
\b([01]\d|2[0-3]):([0-5]\d)\b
или
Код:
\b([01]?\d|2[0-3]):([0-5]\d)\b
- вариант, где часы могут быть из одной цифры
 
В первой половине приняты меры, чтобы ограничиться 0-23 часами, но почему тогда минуты не проверяются? В данный момент поймает и 99 минут.
кусочек ((?: ... )) - непонятен - захватить незахватываемое? Лучше будет так:
Код:
\b([01]\d|2[0-3]):([0-5]\d)\b
или
Код:
\b([01]?\d|2[0-3]):([0-5]\d)\b
- вариант, где часы могут быть из одной цифры
Вы правы. Но это крайне упрощенный пример. Да и, к тому же, использование ?: в нём неактуально. Я лишь не очень-то удачно отметил «более земное» применение, относительно вырвиглазного примера выше — поиск e-mail по RFC822 и 1738 с мелкими упрощениями )
 
Хм. А подскажите, плиззз. Вот это (?: ) работает только если оно не является частью большего подшаблона? В смысле в выражении:
Код:
^(.+?:)\n(.+?)(\t\d{1,2})(?:\r\1\n)(.+?)(?:\3)(?=\r)
оно работает,
а в выражении:
Код:
^(.+?:)\n(.+?)(\t\d{1,2})((?:\r\1\n)(.+?)(?:\3))(?=\r)
не работает.
И я не пойму, я что-то упускаю, или второй вариант в принципе не предусмотрен.
 

Не по теме:
Код:
смайлики веселят

 
Статус
Закрыто для дальнейших ответов.