Секреты регулярных выражений

Ответить
Аватара пользователя
Fenix
Администратор

Секреты регулярных выражений

#1

Сообщение Fenix » 20 июн 2018 16:30

Если задуматься над вопросом: "А что такое "регулярное выражение" вообще?", то ответ найдётся не сразу. Можно сказать, что это специализированный язык описания символьного шаблона (последовательности символов) поиска в строках текста.

Алексей Снастин
В данной теме будем обсуждать правила на основе рег. выражений.
Что получится если?.. почему не получается если?.. :wall:


:pdf icon: Д. Фридл "Регулярные выражения" (3-е издание)

Данная книга откроет вам секрет высокой производительности. Тщательно продуманные регулярные выражения помогут избежать долгих часов утомительной работы и решить свои проблемы за 15 секунд. Ставшие стандартной возможностью во многих языках программирования и популярных программных продуктах, включая Perl, PHP, Java, Python, Ruby, MySQL, VB.NET, C# (и других языках платформы .NET), регулярные выражения позволят вам автоматизировать сложную и тонкую обработку текста.



Общее руководство по шаблонам регулярных выражений без учета специфики какого-либо языка. Включает описание якорей, символьных классов, утверждений, кванторов, групп и диапазонов, модификаторов и т. д.

:pdf icon: Смотреть шпаргалку

Аватара пользователя
evmir_troll-hunter
Администратор

Re: Секреты регулярных выражений

#2

Сообщение evmir_troll-hunter » 28 июн 2018 21:24

wasyaka писал(а): Jan 14 2018

Почему так:
рег выражение (\bвс)е\b(\s([А-Яа-яёЁ\-]+))?(\s([А-Яа-яёЁ\-]+))?(\s([А-Яа-яёЁ\-]+))?(\s\b(мелочи|мелочи)\b)=$1<:yo:>$2$4$6$8

срабатывает во всех случаях - от все мелочи до все 1-3 слова мелочи
но только при условии что $8 (последжние скобки) из двух и более слов?
Хорошая штука научный тык (2часа тыкал, брал одно слово и тЭстировал... :wall: вместо :russian: хорошо догадался совместить...), но всё же, почему? :scratch:

Аватара пользователя
MoppoH
Обыватель

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

#3

Сообщение MoppoH » 24 июл 2018 20:48

Очень интересное обсуждение рег выражений пошло у нас [...] предлагаю скидывать свои выражения, обсуждать как улучшить чужие.
wasyaka писал(а):
24 июл 2018 12:23
\s?(\w+)? -? означает может присутствовать, а может и нет
вот тут не понял, что после \s может еще присутствовать там между двумя словами?
tonio_k писал(а):
24 июл 2018 13:48
- в среднем длина слова в русском языке - 7 символов. 10 - это я с расчетом на "чуть выше средней" длины слова.
как показала многолетняя практика рассчитать количество символов практически не возможно, сейчас стараюсь уйти от этого вот таким путем
(?i)\bвсе\b(?=.[\S]*(апно|асно|енно|ично|ливо|ль[кн]о|стро|точно)\b.[\S]+(!али|атся|ают|(в|м|н|ч)али|ваны|дели|емся|\Bили|лены|лись|нили|сели|ыкли|яли|ятся)\b)
а то часто бывают ложные срабатывания
wasyaka писал(а):
24 июл 2018 12:23
( \s(\w+)?){1,}) - используется всё предложение (пропущенные(не использованные для правила) слова до ключевого заменяются пробелом) и это грубое правило, ниже(далее) по словарю более точные и т.д. отсюда и \s{1,4}, в отличии от KoobAudio где срабатывание на "первом встречном" и как бы наизнанку от точного к размытому .Из-за этого я и отказался от проги и перешёл на REX.
чем плохо что используется все предложение, тем что оба слова уже забиты одним рег выражением, и если допустим прилагательное + омограф уже найдено, то это прилагательное уже не пойдет к другому омографу
типа такого, дырявые трубы или печи, заменит только один из омографов
tonio_k писал(а):
24 июл 2018 01:55
Не спорю хитро сделано в итоге знак "< " на последнюю букву для каждого слова на конце, что для Николая - самое то, а вот для Максима - не подходит.
не понял в чем проблема со знаком <, можно добавить в словарик для Максима такое выражение
\Bы<=Ы, и после обработки он заменит все < на большие буквы для Максима

Аватара пользователя
tonio_k
V.I.P.

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

#4

Сообщение tonio_k » 24 июл 2018 21:33

MoppoH писал(а):
24 июл 2018 20:48
вот тут не понял, что после \s может еще присутствовать там между двумя словами?
смысл этого выражения-правило сработает в обоих случаях: 1) между 2 искомыим словами присутствует ещё одно любое слово в связке с пробелом перед ним.
2) между этими двумя искомыми словами только пробел

Аватара пользователя
wasyaka
V.I.P.

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

#5

Сообщение wasyaka » 24 июл 2018 22:51

MoppoH писал(а):
24 июл 2018 20:48
чем плохо что используется все предложение, тем что оба слова уже забиты одним рег выражением, и если допустим прилагательное + омограф уже найдено, то это прилагательное уже не пойдет к другому омографу
типа такого, дырявые трубы или печи, заменит только один из омографов
не так поняли:
Увидим кусок берега
#(?i)(?<=(забрызгивала|осмотрел|увидим)[^\.,!?-]{0,30})\bберега\b=берега<
Увидим кусок берегА
И ниже у Вас правило
#(?i)(?<=((вы|у)ступ|глубин|заросли|кусок|обрыв|полоск|приближение)[^\.,!?-]{0,30})\bберега\b=бе<рега
Оно и останится правилом - но не сработает в данном и во многих других случаях...
► Показать
Это чем реги в dic отличаются от rex
В rex сработает последнее самое точное как фильтр грубая-средняя-тонкая очистка...
► Показать

Аватара пользователя
MoppoH
Обыватель

Секреты регулярных выражений

#6

Сообщение MoppoH » 24 июл 2018 23:46

если я правильно понял, dic срабатывает первое в списке рег выражение, а в rex последнее?
просто в этих выражениях не понятно какое из них сработает
#(?i)(?<=((вы|у)ступ|глубин|заросли|кусок|обрыв|полоск|приближение)[^\.,!?-]{0,30})\bберега\b=бе<рега
#(?i)(?<=(забрызгивала|осмотрел|увидим)[^\.,!?-]{0,30})\bберега\b=берега<
если у меня в словаре они идут в таком порядке, то замети на Увидим кусок бе<рега, а второго проигнорирует
KooBAudio_2018-07-24_23-43-11.png
KooBAudio_2018-07-24_23-43-11.png (87.67 КБ) 2206 просмотров

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#7

Сообщение tonio_k » 24 июл 2018 23:54

MoppoH, правила в балаболке в словарях bxd обрабатываются строго по порядку - как записаны в словаре. Последующее правило переписывает результаты срабатывания предыдущего. Правила в формате REX могут чередоваться с DIC в любой комбинации - срабатывание будет по порядку их нахождения в словаре bxd. BXD это новый формат словаря - гибрид. В нем можно заводить строки правил как в формате DIC так и в REX в нужной для пользователя последовательности


Отправлено спустя 34 минуты 16 секунд:
С Максимом удобство в том, что можно одно и то же слово поменять несколько раз разными правилами. А вот с Николаем ситуация немного другая. Изменив в тексте берега на бе<рега слово берегав тексте уже отсутствует. И дальнейшие уточняющие правила уже не могут это слово отловить. Поэтому "последовательная" обработка вам не приемлема. Если вы не перелопатите все свои словари на схему:
берега=бЕрега

А в самом конце уточняющий соварь проставляющий ударения под Николая:
$*бЕ*=бе<
Схема условная в формате dic


Отправлено спустя 7 дней 12 часов 51 минуту 33 секунды:
MoppoH, для себя (пока) нашел такой простой способ поиска вместо ранее используемого мною [^\.,!?-]{0,30} - "примерно" три слова между искомыми словами. Теперь буду пытаться применять (|\w+\s|\w+\s\w+\s|\w+\s\w+\s\w+\s) - т.е. конкретно от 0 до 3 слов
Пример
\bмежду\b\s\b(нами|ними|вами)\b\s(|\w+\s|\w+\s\w+\s|\w+\s\w+\s\w+\s)(\bпропасть\b)=между $1 $2 прОпасть
Сработает на:
Между вами пропасть
Между вами большая пропасть
Между вами самая большая пропасть
Между вами огромная по величине пропасть

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#8

Сообщение wasyaka » 01 авг 2018 15:57

tonio_k писал(а):
01 авг 2018 13:20
(|\w+\s|\w+\s\w+\s|\w+\s\w+\s\w+\s) - т.е. конкретно от 0 до 3 слов
Пример
(| - уже ошибка
((\s(\w+)?){1,})>((\s(\w+)?){1,2})>((\s(\w+)?){1,3}) и т.д.???
tonio_k писал(а):
01 авг 2018 13:20
Если вы не перелопатите все свои словари на схему:
берега=бЕрега
И потом прослезитесь...:cry_baby:
см. картинку
110391...
110392 и т.д

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#9

Сообщение tonio_k » 01 авг 2018 16:27

wasyaka писал(а):
01 авг 2018 15:57
(| - уже ошибка
нет не ошибка. Это как раз тот самый 0 слов между искомыми.
wasyaka писал(а):
01 авг 2018 15:57
((\s(\w+)?){1,})
согласен, но большое количество скобок 2 или 3 в одном создаёт проблему с определением возврата переменной: $4 или $7 надо указать после равно? что бы результаты были не в перемешку? Для меня это вычислять очень сложно - только методом проб и ошибок. А "мой вариант" простой линейный и предсказуемый. Только один вариант вариант в скобках "()". Т.е. $1 или $2 - определить легко, он будет по порядку.

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#10

Сообщение wasyaka » 01 авг 2018 20:02

tonio_k писал(а):
01 авг 2018 16:27
согласен, но
Каждый выбирает по себе...
а MoppoH вообще автор регов для омографов в KooBAudio :thank: ... я лиш ученик и продолжатель в rex :drunkpals:

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#11

Сообщение tonio_k » 02 авг 2018 01:17

Задача - удалить задвоенные пробелы в тексте.
Вопрос, почему результаты разные?

Код: Выделить всё

( ){2,}=$1
(в скобках пробел) -норм отрабатывает

Код: Выделить всё

(\s){2,}=$1
- сбиваются абзацы в один сплошной текст

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

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#12

Сообщение wasyaka » 02 авг 2018 07:18

tonio_k писал(а):
02 авг 2018 01:17
(\s){2,}=$1
- сбиваются абзацы в один сплошной текст
У меня в bxd срабатывает нормально

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#13

Сообщение tonio_k » 02 авг 2018 10:52

wasyaka писал(а):
02 авг 2018 07:18
в bxd
► Показать

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#14

Сообщение wasyaka » 02 авг 2018 13:22

► Показать

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#15

Сообщение tonio_k » 02 авг 2018 13:48

когда это правило одно в словаре т.е. в идеальнх условиях действительно почему-то все корректно.
А вот попробуйте в 1.5. homographs.bxd - в самый конец добавить (\s){2,}=$1 вместо (\s)(\s)=$1 и прогнать текст.

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#16

Сообщение wasyaka » 02 авг 2018 19:56

tonio_k писал(а):
02 авг 2018 13:48
обавить (\s){2,}=$1 вместо (\s)(\s)=$1

А зачем это?
В Балаболке нет "красной" строки - соответственно абзац от абзаца отделяют два пробела которые (\s){2,}=$1 (от двух и до луны :big_smile: ) убираются, соответственно и текст сбивается, из-за этого и (\s)(\s)=$1 - убирается один пробел...
А вообще для этих целей существует форматирование текста в самой проге
► Показать

Аватара пользователя
MoppoH
Обыватель

Секреты регулярных выражений

#17

Сообщение MoppoH » 04 авг 2018 20:23

tonio_k писал(а):
01 авг 2018 13:20
Пример
\bмежду\b\s\b(нами|ними|вами)\b\s(|\w+\s|\w+\s\w+\s|\w+\s\w+\s\w+\s)(\bпропасть\b)=между $1 $2 прОпасть
Сработает на:
Между вами пропасть
Между вами большая пропасть
Между вами самая большая пропасть
Между вами огромная по величине пропасть
очень понравилась такая идея не искать количество символов возле слова, а искать именно число слов возле слова, как мне кажется так поиск идет более четко, вот у меня получилось такое выражение
#(?i)\bзадвигал\b(?=\s(\w+\s){0,4}[^\.,!?-]?(ящик))=задвигАл
ищет от 0 до 4 слов после слова задвигал и если нет знаков препинания

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#18

Сообщение tonio_k » 05 авг 2018 00:34

MoppoH, везет вам - не требуется указывать $1 $2...$7 после равно :big_smile:
попробовал ваш пример подогнать под Демагог/Балалболку.
Задвигал за ширму ящик Первый сюрприз - вот совсем не $1 после равенства, хотя казалось бы есть общая скобка и вроде бы она должна быть первой:
\bзадвигал\b(?=\s(\w+\s){0,4}[^\.,!?-]?(ящик))=задвигАл $3
добавляю в текст запятую (а тут убираю: [^\.!?-])- все равно не срабатывает во всех случаях при наличии запятой в тексте
MoppoH писал(а):
04 авг 2018 20:23
если нет знаков препинания
\bзадвигал\b(?=\s(\w+\s){0,4}[^\.,!?-]?(ящик))=задвигАл а разве выделеный участок как раз и не предполагает отсутствие какого либо знака препинания? Это же слово и сразу пробел после него. А [^\.,!?-] - подразумевает отсутствие знака препинания только перед словом ящик. Хотя обязательный пробел после \w - так же и запрещает знак препинания?

Предыдущий пример:
\bмежду\b\s\b(нами|ними|вами)\b\s(|\w+\s|\w+\s\w+\s|\w+\s\w+\s\w+\s)(\bпропасть\b)=между $1 $2 прОпасть
Немного сократил:
\bмежду\b\s\b(нами|ними|вами)\b\s(|\w*\s*\w*\s*\w*\s*)(\bпропасть\b)=между $1 $2 прОпасть
То же но с учетом наличия в тексте запятой:
\bмежду\b\s\b(нами|ними|вами)\b\s(|\w*\,*\s*\w*\,*\s*\w*\,*\s*)(\bпропасть\b)=между $1 $2 прОпасть

Аватара пользователя
MoppoH
Обыватель

Секреты регулярных выражений

#19

Сообщение MoppoH » 05 авг 2018 11:56

tonio_k писал(а):
05 авг 2018 00:34
\bзадвигал\b(?=\s(\w+\s){0,4}[^\.,!?-]?(ящик))=задвигАл а разве выделеный участок как раз и не предполагает отсутствие какого либо знака препинания?
не знаю как в других читалках работают рег выражения напишу как в кубаудио это ищет
\bзадвигал\b ищет целиком слово в тексте
(?=\s эта часть показывает что между словом что ищет и другим есть пробел
(\w+\s) показывает что надо найти слово с пробелом
{0,4} показывает что слов с пробелом должно быть от 0 до 4
[^\.,!?-]? это определяет что между этими словами от 0 до 4 не должно быть знаков препинания
(ящик)) означает какое слово должно быть в связке с искомым омографом

не знаю как точно должно работать оно у вас но типа такого должно сработать
\bзадвигал\b(\s(\w+\s){0,4}[^\.,!?-]?)(сундук|чемодан|ящик)=задвигАл $1 $+

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#20

Сообщение tonio_k » 06 авг 2018 10:36

MoppoH писал(а):
05 авг 2018 11:56
[^\.,!?-]? это определяет что между этими словами от 0 до 4 не должно быть знаков препинания
мне видется, что этот запрет в правиле лишний. Т.е. от него нет смысла. У вас в правиле ищется от 0 до 4 связка: "словопробел" эта связка сама по себе будет игнорировать связку "словозапятаяпробел". Другое дело, что без [^\.,!?-] само правило по каким то технически причинам не работает - типа обязательно аргумента.

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#21

Сообщение wasyaka » 07 авг 2018 10:46

tonio_k писал(а):
06 авг 2018 10:36
Другое дело, что без [^\.,!?-] само правило по каким то технически причинам не работает
► Показать

Код: Выделить всё

(\w+(|)\b\s?(\w+)?)\s{1,4}(\b\b)=$1 
(\b(|)(\w+)?(\s(\w+)?){1,})(\b\b)=$1 
(\b(|)(\w+)?\s?(\w+)?)\s{1,4}\b(и|или|с)\b\s{1,4}(\b\b)=$1 $5 
(\b(|)\b\s?(\w+)?)\s{1,4}\b(и|или|с)\b\s{1,4}(\b\b)=$1 $4 
(\b(|)\b\s?(\w+)?)\s{1,4}(\b\b)=$1 
\b(|)\b\s{1,4}(\b\b)=$1 

(\b\b)(\s?(\w+)?\s{1,4}(\w+(|)\b))= $2
(\b\b)((\s(\w+)?){1,}(|)(\w+)?)= $2
(\b\b)\s{1,4}\b(и|или|с)\b(\s?(\w+)?\s{1,4}\b(|)\b)= $2 $3
(\b\b)(\s?(\w+)?\s{1,4}\b(|)\b)= $2
(\b\b)\s{1,4}\b(|)\b= $2
(\b\,)\s{1,4}\b(|)\b=, $2

\b(|)\b\s{1,4}(\b\b)\s{1,4}\b(|)\b=$1 XXX $3
@(\b\b)\s{1,4}\b([А-ЯЁ]\w+)\b= $2
@(\b\b)\s{1,4}\b([А-ЯЁ](\w+)?)= $2
(\…|\.|\,|\!|\?|\:|\;|\-)\s(\b\b)(\…|\.|\,|\!|\?|\:|\;|\ -)=$1 ххх$3



Отправлено спустя 10 часов 25 минут 18 секунд:
wasyaka писал(а):
07 авг 2018 10:46
(\b\b)
омограф в скобках для общей унификации и предотвращения путаницы с $

Код: Выделить всё

(\w+(|)\b\s?(\w+)?)\s{1,4}\b(авиа|мех)?(корпуса\b)=$1 $4корпусА
(\b(|)(\w+)?(\s(\w+)?){1,})\b(авиа|мех)?(корпуса\b)=$1 $6кОрпуса
(\b(|)\b\s?(\w+)?)\s{1,4}\b(и|или|с)\b\s{1,4}\b(авиа|мех)?(корпуса\b)=$1 $4 $5корпусА
\b(|)\b\s{1,4}\b(авиа|мех)?(корпуса\b)=$1 $2корпусА
\b(авиа|мех)?(корпуса\b)(\s?(\w+)?\s{1,4}(\w+(|)\b))=$1кОрпуса $3
\b(авиа|мех)?(корпуса\b)((\s(\w+)?){1,}(|)(\w+)?)=$1корпусА $3
\b(авиа|мех)?(корпуса\b)\s{1,4}\b(|)\b=$1корпусА $3
\b(авиа|мех)?(корпуса\b)=$1$2
Для многих пар омографов (редких) шаблоны работают практически без ошибочно, а для часто встречаемых - индувидуальный подход...
Это как Восток - :big_smile: дело тонкое

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#22

Сообщение tonio_k » 12 окт 2018 00:47

Пример правила:
\bвсё\b=всЪё
\bвсЪё\b=всё

под это правило попадают все варианты слов с разными регистрами: всё, Всё, всЁ, ВСЁ
а на выходе всегда будет всё
Вопрос, как прописать, что бы на выходе было слово всё но с таким же регистром букв, как первоначально


Отправлено спустя 6 минут 25 секунд:
Туплю на ночь глядя :facepalm: Каждый вариант прописать через @ (учёт регистра) и всего делов. Но может есть какое то написание, что бы в одну строку прописать?

Аватара пользователя
Arex
Интересующийся

Секреты регулярных выражений

#23

Сообщение Arex » 14 окт 2018 09:52

tonio_k писал(а):
02 авг 2018 01:17
(\s){2,}=$1
- сбиваются абзацы в один сплошной текст
В это множество входят не только пробелы, но и табуляции, и переносы строк (\r и \n), так что не удивительно.
tonio_k писал(а):
12 окт 2018 00:53
Вопрос, как прописать, что бы на выходе было слово всё но с таким же регистром букв, как первоначально
Не очень понимаю, зачем нужна замена, которая не меняет ничего?

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#24

Сообщение tonio_k » 14 окт 2018 10:45

Arex писал(а):
14 окт 2018 09:52
Не очень понимаю, зачем нужна замена, которая не меняет ничего?
вот тут смысл приводится: https://www.mytts.info/viewtopic.php?p=153#p153

Аватара пользователя
Arex
Интересующийся

Секреты регулярных выражений

#25

Сообщение Arex » 14 окт 2018 11:21

Понятно.
Тогда в начале

Код: Выделить всё

\b(всё)\b=$1Ъ
а в конце

Код: Выделить всё

\b(всё)Ъ\b=$1
Так регистр сохранится.

Если же хочется именно "всЪё", можно так

Код: Выделить всё

\b(вс)(ё)\b=$1Ъ$2
\b(вс)Ъ(ё)\b=$1$2

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#26

Сообщение tonio_k » 01 дек 2018 17:40

tonio_k писал(а):
05 авг 2018 00:34
\bмежду\b\s\b(нами|ними|вами)\b\s(|\w*\s*\w*\s*\w*\s*)(\bпропасть\b)=между $1 $2 прОпасть
еще короче и удобнее применять такой блок: ((\s*\w*\s*){3})
в данном примере {3} - максимально допустимое количество вхождений слов т.е. от 0 до 3
получаем:

\b(между)\s+(нами|ними|вами)\b((\s*\w*\s*){3})\s+(пропасть)\b=между $2$3 прОпасть

Для не гарантии срабатываний - лучше всего вместо одного пробела всегда указывать \s+ (или " +" - пробел и квантификатор). Регулярные выражения на выходе иногда очень странные результаты по количеству пробелов выдают.

\b\s или \b\s\b или \s\b лучше сразу заменить на \s+

Не обязательно вводить ограничение слова \b если после последней буквы или перед первой буквой слова все равно идет пробел


Отправлено спустя 1 час 56 минут 37 секунд:
К сожалению ((\s*\w*\s*){3}) иногда выдает неверные результаты.
Поэтому, (\s*\w*\s*) - до 1 любого слова (\s*\w*\s*\w*\s*) - до 2 любых слов и т.д. пока самая стабильная комбинация.

Аватара пользователя
MoppoH
Обыватель

Секреты регулярных выражений

#27

Сообщение MoppoH » 02 дек 2018 15:17

tonio_k писал(а):
01 дек 2018 19:37
К сожалению ((\s*\w*\s*){3}) иногда выдает неверные результаты.
а есть пример где он выдает неверный результат? у меня вот такое в этом выражение (нами|ними|вами)(\s\w*){0,4} поиск от 0 до 4 слов

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#28

Сообщение tonio_k » 02 дек 2018 17:02

MoppoH писал(а):
02 дек 2018 15:17
выдает неверный результат?
(\bзаявитесь\b)\s+((\s*\w*\s*){3})(\bраньше\b)=заЯвитесь $2 $3

Если вы заявитесь на много раньше, чем это нужно.

выдает такой результат:
если вы заЯвитесь на много , чем это нужно

Я ожидаю что:
((\s*\w*\s*){3}) будет захвачен $2
(\bраньше\b) будет захвачен $3
но на деле это не так. Нужно добавлять $4. А мне так не нравиться - это не так "явно" хочу что бы правило было простым - сколько закрытых скобок, столько и захватов. И если скобки в скобках, то ожидаю, что берутся в захват именно первые и последние, а не те, что внутри.


Отправлено спустя 47 минут 8 секунд:
сейчас я применяю такие блоки:
\s+(\s*\w*\s*)\b
- если хочу повысить верхний предел слов то дублирую \w*\s* на нужное количество слов:
\s+(\s*\w*\s*\w*\s*)\b - 2 слова
\s+(\s*\w*\s*\w*\s*\w*\s*)\b - 3 слова

Если надо заложить больше трех слов, то уже можно и такой применить:
\b([^\.,!?-]*)\s+

\b и \s+ меняю местами по смыслу

Аватара пользователя
balaamster
Обыватель

Секреты регулярных выражений

#29

Сообщение balaamster » 02 дек 2018 18:39

tonio_k писал(а):
02 дек 2018 17:49
выдает такой результат:
если вы заЯвитесь на много , чем это нужно
tonio_k писал(а):
02 дек 2018 17:49
А мне так не нравиться - это не так "явно" хочу что бы правило было простым - сколько закрытых скобок, столько и захватов
Все захваты нумеруются последовательно. Условно говоря, по открывающей скобке.
Чтобы захват не нумеровался, нужно перед открывающей скобкой поставить ?:

(\bзаявитесь\b)\s+((?:\s*\w*\s*){3})(\bраньше\b)=заЯвитесь $2 $3
Если первая группа не используется в подстановке, то её вообще можно не захватывать:
\bзаявитесь\s+((?:\s*\w*\s*){3})(\bраньше\b)=заЯвитесь $1 $2

Аватара пользователя
MoppoH
Обыватель

Секреты регулярных выражений

#30

Сообщение MoppoH » 02 дек 2018 18:57

либо указывать в рег выражение $+ указывающий последнюю группу
(\bзаявитесь\b)\s+((\s*\w*\s*){3})(\bраньше\b)=заЯвитесь $2 $+


Отправлено спустя 19 минут 14 секунд:
в идеале оно должно выглядеть вот так
\bзаявитесь\b\s+((?:\s*\w*\s*){0,3})(\bраньше\b)=заЯвитесь $1 $+

\bзаявитесь\b - искомое слово
\s+ - пробел один или более
((?:\s*\w*\s*){0,3}) - пассивная группа, которая не учитывается для замены только для поиска от 0 до 3 слов
(\bраньше\b) - контрольное слово для поиска

Аватара пользователя
tonio_k
V.I.P.

Секреты регулярных выражений

#31

Сообщение tonio_k » 02 дек 2018 20:45

\b(заявитесь)\b((?:\s*\w*\s*){3})\b(раньше)\b=заЯвитесь $2 $3
интересно, почему без \s+ не срабатывает?


Отправлено спустя 1 день 2 часа 53 минуты 19 секунд:
\b(в|ваши|вс[её]|всеъ|да|ей|за|им|их|как|на|на [егоёих]{1,3}|наши|них|по|про|продолжить|свои|твои|там|те|те же|через|чьи|эти|это)\b((?:\s*\w*\s*){1})\s+(бега)\b=$1$2 бегА

ваши один два три четыре пять бега

5 слов между ваши и бега а правило все равно срабатывает. :sad:

Аватара пользователя
wasyaka
V.I.P.

Секреты регулярных выражений

#32

Сообщение wasyaka » 04 дек 2018 08:50

tonio_k писал(а):
03 дек 2018 23:38
\b(заявитесь)\b((?:\s*\w*\s*){3})\b(раньше)\b=заЯвитесь $2 $3
Где-ударение.рф

В данном слове допускается ставить ударение либо на слог с буквой Я — заЯвитесь, либо на слог с буквой И — заявИтесь. :search:

Аватара пользователя
good_cat
V.I.P.

Секреты регулярных выражений

#33

Сообщение good_cat » 04 дек 2018 09:03

Морфологический разбор слова «заявитесь»:

Зая́витесь — 2 л., мн.ч., действ. залог, буд. вр., изъявит. накл. слова «заявиться».

Заяви́тесь — мн.ч., повелит. накл., действ. залог слова «заявиться».

Ответить

Вернуться в «Разное»