Регулярные выражения

Russian main discussion
  • Author
  • Message
Offline
Posts: 294
Joined: Tue Jul 27, 2010 11:18 pm

Post by Serge Yolkin »

Drugmix
Э-э-э... Похоже, мне требуется переводчик. Про (?= я знаю, меня озадачило выражение (?> , про которое Вы написали
теперь работает
...

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

я криво выразился. Я думал, что YuS не в курсе про добавленные positive/negative look ahead/behind'ы. Они теперь работают. Просто в AP positive look ahead реализован через (?= который легко перепутать с (?> по аналогии с positive look behind (?<

Возможно, стоило бы приравнять (?> к (?= и разрешить двоякое употребление.

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Drugmix wrote:YuS
теперь работает, просто оно лишнее там.
Если оно работает так, как именно написано, то оно вовсе не лишнее, ибо вопрос был задан про:
Cкажите, что быстрее
а это наиболее быстрая из видов групп в регулярках, т.к. в ней нет возврата по строке и она запрещает проверку при первом же найденном варианте внутри группы.
Drugmix wrote: Возможно, стоило бы приравнять (?> к (?= и разрешить двоякое употребление.
Это не одно и то же...
Last edited by YuS on Sun Feb 09, 2014 5:38 am, edited 1 time in total.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

YuS
О как. Я не знал.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Выражение:

Code: Select all

^(`[^\n\r]+?[^\.!:])<br>$
Текст для проверки:

Code: Select all

Don't change me<br>
`but change me<br>
`and me<br>
`except me!<br>
Предполагается замена на

Code: Select all

\1.<br>
(в SearchReplace.js работает)

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Infocatcher
Все верно. Попробуйте поискать

Code: Select all

`[^\n\r]+?[^\.!:]
, чтобы понять почему не находит. Для данной задачи можно так:

Code: Select all

^(`[^\n\.!:]+?)<br>$

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

Instructor
судя по тому, как было составлено правило у Infocatcher'а - предполагаю, что ему нужно было составить шаблон так, чтобы замена сработала и на строках, содержащих !.:, но только если они идут не последним символом перед <br>.
Ваше же правило не сработает ни на одной из этих строк:

Code: Select all

`.change me<br>
`and me too! please<br>
`me: wants to be changed too<br>
Поэтому для данной задачи, видимо, лучше как-то так:

Code: Select all

^(`[^\n\r]+?)(?<![\.!:])<br>$
Last edited by Drugmix on Wed Feb 12, 2014 3:36 pm, edited 1 time in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Instructor wrote:Для данной задачи можно так:

Code: Select all

^(`[^\n\.!:]+?)<br>$
То есть если требуется разрешить точки в строках (но не в конце), то ничего не сделать? Типа вот такого:

Code: Select all

`Also. Should. Be. Changed<br>

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Drugmix wrote:Поэтому для данной задачи, видимо, лучше как-то так:

Code: Select all

^(`[^\n\r]+?)(?<![\.!:])<br>$
Спасибо, это гораздо лучше.
Только не понятно, в чем тут отличие с точки зрения редактора.
То есть почему не работает мой вариант понятно (но это все равно не радует), а вот почему (с учетом предыдущего) работает шаманство с (?<! ...) – не понятно.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

Infocatcher wrote:Только не понятно, в чем тут отличие с точки зрения редактора.
То есть почему не работает мой вариант понятно (но это все равно не радует), а вот почему (с учетом предыдущего) работает шаманство с (?<! ...) – не понятно.
Группа перед (?<!…) - жадная и съедает всё что может да побольше, (поэтому твой вариант и не работал, т.к. второй группе не оставалось на съедение даже 1 символа, а 1 символ не может съедаться разными группами дважды).
А (?<!…) - группа, которая не ест, и работает как фильтр: выполняет проверку символов слева и если надо - отменяет работу всего выражения целиком.

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Infocatcher wrote:То есть если требуется разрешить точки в строках (но не в конце), то ничего не сделать? Типа вот такого:

Code: Select all

`Also. Should. Be. Changed<br>
Это не совсем так. Учитывая тот факт, что групп может быть больше чем одна, то вполне реализуется вот такой вариант:

Code: Select all

Что: ^(`[^\n\r]+?)([^.!:])<br>$
Чем: \1\2.<br>
Infocatcher wrote: Только не понятно, в чем тут отличие с точки зрения редактора.
То есть почему не работает мой вариант понятно (но это все равно не радует), а вот почему (с учетом предыдущего) работает шаманство с (?<! ...) – не понятно.
Ну, как же? Отличие значительное, ведь negative lookbehind вполне работает по своему назначению, т.е. если буквально прочитать выражение:
Совпадает, если сразу за началом строки следуют символ "`", далее следует один или более символов "[^\n\r]", в наименьшем возможном сочетании и при условии отсутствия в последнем символе любого из перечисленных в классе "[\.!:]", далее следуют символы "<br>$" - как-то так.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

EDIT: разобрался.
Last edited by Drugmix on Thu Feb 13, 2014 11:55 pm, edited 1 time in total.

Offline
Posts: 4
Joined: Sun May 12, 2013 8:56 am

Post by bayzhanov »

Подскажите а как реализовать поиски такого типа:
Предположим даны буквы "аеикмнопрстучя" и словарь русского языка в txt.
Задача: составь из этих букв как можно больше слов(читай поиск в словаре), НО буквы не повторяются( т.е. например буква "а" может в слове встречаться только 1 раз).
Вот как мне кажется решение с повторами букв:
egrep -w '[аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя][аеикмнопрстучя]' rus.txt

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

bayzhanov, "Эрудит" какой-то играете чтоли? ))
Обратились бы на спец ресурс по регуляркам.
Надеюсь число букв в слове конечно и определенно?
Идея есть, для малого количества букв даже в голову регулярка вкладывается, и добавление очередной буквы операция в общем то однотипная , но размер регулярки будет расти в геометрической прогрессии.
Идея такая:
для 1-буквенного слова: [набор] понятно.
(Для простоты обозначим этот [набор] как Q что-бы не загромождать текст)
для 2-буквенного слова: (Q)(?=Q)([^\1]) т.е 1 буква - одна из набора. вторая из 2х частьей:
(?=Q) - positive lookahead - "проверить, не подходит ли текущая позицая к регулярке Q нашему набору, но не захватывать)
([^\1]) - захватить любой символ кроме того который был захвачен ранее.
3 буквы: (Q)(?=Q)([^\1])(?=Q)([^\1\2]) - суть выделенного фрагмента выше описано.
Ну и далее выделенный и дополненный фрагмент дописываем. Имее в итоге

Code: Select all

1:(Q)
2:(Q)(?=Q)([^\1])
3:(Q)(?=Q)([^\1])(?=Q)([^\1\2])
4:(Q)(?=Q)([^\1])(?=Q)([^\1\2])(?=Q)([^\1\2\3])
5:(Q)(?=Q)([^\1])(?=Q)([^\1\2])(?=Q)([^\1\2\3])(?=Q)([^\1\2\3\4])
6:(Q)(?=Q)([^\1])(?=Q)([^\1\2])(?=Q)([^\1\2\3])(?=Q)([^\1\2\3\4])(?=Q)([^\1\2\3\4\5])
7:(Q)(?=Q)([^\1])(?=Q)([^\1\2])(?=Q)([^\1\2\3])(?=Q)([^\1\2\3\4])(?=Q)([^\1\2\3\4\5])(?=Q)([^\1\2\3\4\5\6])
8:(Q)(?=Q)([^\1])(?=Q)([^\1\2])(?=Q)([^\1\2\3])(?=Q)([^\1\2\3\4])(?=Q)([^\1\2\3\4\5])(?=Q)([^\1\2\3\4\5\6])(?=Q)([^\1\2\3\4\5\6\7])
Не забываем ^ и $ в начале и конце выражения.
В итоге один такой червяк ищет слово по указанному критерию. Сразу всплывает ограничение: backref-ов в большинстве движков может быть только 9: \1-\9, а значит подобное выражение может поймать максимум 10-буквенное слово.
При этом набор Q=[набор] может быть и длинее чем кол-во букв в слове, но не короче, иначе конец регулярки будет всегда отказывать: (?=[abc]) сработает, но [^abc] откажет.

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

Домашнее задание: модифицировать регулярку так, чтобы находила и слова по-короче. Сдать до пятницы. :D

Offline
Posts: 4
Joined: Sun May 12, 2013 8:56 am

Post by bayzhanov »

не работает (((
Post Reply