подвыражение в рубби

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Аватара пользователя
jojahti
Сообщения: 310

подвыражение в рубби

Сообщение jojahti »

Выражение номер раз:

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

/\/[^\/]*$/

Выражение номер два:

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

/(\/)[^\/]*$/


Первый символ взят в скобки и выражение начинает работает так, словно после этих скобок выражение заканчивается, или звёздочка перестаёт быть жадной. :unsure:
Спасибо сказали:
Аватара пользователя
jojahti
Сообщения: 310

Re: подвыражение в рубби

Сообщение jojahti »

В ходе экспериментов выяснилось, что во втором случае у меня получается обозначение имеющее смысл обратный позитивному заглядыванию вперёд.(это так в книжке называется, хз. правильно - неправильно, как-то коряво звучит).
Даа, руби такой простой и понятный язык, самое оно в школах изучать. :happy:
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

jojahti писал(а):
23.02.2011 17:02
Даа, руби такой простой и понятный язык, самое оно в школах изучать.

я тоже считаю, что перловые регулярки не нужны :)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
jojahti
Сообщения: 310

Re: подвыражение в рубби

Сообщение jojahti »

drBatty
я тоже считаю, что перловые регулярки не нужны :)

А как тогда поиск по регуляркам делать?
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

drBatty писал(а):
23.02.2011 18:09
jojahti писал(а):
23.02.2011 17:02
Даа, руби такой простой и понятный язык, самое оно в школах изучать.

я тоже считаю, что перловые регулярки не нужны :)

В perl все нормально — различие только в захвате «/» в переменную $1, как и должно быть. ruby к сожалению нет, проверить как работает там не могу.

jojahti писал(а):
23.02.2011 18:49
drBatty
я тоже считаю, что перловые регулярки не нужны :)

А как тогда поиск по регуляркам делать?

perl-ом ☺. Или sed. Или grep. А на каком наборе данных вы их запускаете?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

jojahti писал(а):
23.02.2011 18:49
А как тогда поиск по регуляркам делать?

используйте glibc. например через sed. оно быстрее.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
jojahti
Сообщения: 310

Re: подвыражение в рубби

Сообщение jojahti »

liaonau
А на каком наборе данных вы их запускаете?

Текст разбираю.

Вообще мне нужно было исключить из результирующей строки первый её символ:
/s(tring)/
"string".scan(/s(tring)/) #=> tring

А действие обратное, когда нужно исключить всё кроме первого символа будет:
/s(?=tring)/
"string".scan(/s(?=tring)/) #=> s

А в перле значение шаблона /s(tring)/ то же самое что и в руби получится, то есть исключение s из результирующего выражения? А то я регулярные выражения только по виму знаю, мне их /dev/random "преподавал". :D Так вот там /s(tring)/ идентично /string/ , что меня и запутало.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

jojahti писал(а):
23.02.2011 19:22
А действие обратное, когда нужно исключить всё кроме первого символа будет:
/s(?=tring)/
"string".scan(/s(?=tring)/) #=> s

s/(.).*/\1/
не?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
jojahti
Сообщения: 310

Re: подвыражение в рубби

Сообщение jojahti »

Ну да, или так - взять в скобочки первый элемент, но в этом случае ты оставляешь только первый элемент.
А я говорил про исключение всех кроме первого. :)
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

drBatty писал(а):
23.02.2011 19:47
jojahti писал(а):
23.02.2011 19:22
А действие обратное, когда нужно исключить всё кроме первого символа будет:
/s(?=tring)/
"string".scan(/s(?=tring)/) #=> s

s/(.).*/\1/
не?

Если нужно оставить только первый символ (и никаких других задач), то здесь вообще регулярные выражения излишни. Достаточно cut.

jojahti писал(а):
23.02.2011 19:58
Ну да, или так - взять в скобочки первый элемент, но в этом случае ты оставляешь только первый элемент.
А я говорил про исключение всех кроме первого. :)

Брр… А в чем разница то?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

jojahti писал(а):
23.02.2011 19:58
Ну да, или так - взять в скобочки первый элемент, но в этом случае ты оставляешь только первый элемент.
А я говорил про исключение всех кроме первого.

не вижу разницы.
liaonau писал(а):
23.02.2011 20:02
Если нужно оставить только первый символ (и никаких других задач), то здесь вообще регулярные выражения излишни. Достаточно cut.

я знаю.
так как звучит ваша задача?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

jojahti писал(а):
23.02.2011 19:22
А действие обратное, когда нужно исключить всё кроме первого символа будет:
/s(?=tring)/
"string".scan(/s(?=tring)/) #=> s

Заглядывание вперед надо чтобы ваше регулярное выражение не отхватило лишнего (удостовериться, что впереди что-то есть). А вам же все равно, вы хотите отсечь все кроме первого символа.
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

jojahti писал(а):
23.02.2011 19:22
А в перле значение шаблона /s(tring)/ то же самое что и в руби получится, то есть исключение s из результирующего выражения? А то я регулярные выражения только по виму знаю, мне их /dev/random "преподавал". :D Так вот там /s(tring)/ идентично /string/ , что меня и запутало.

Нет не идентично, скобки захватывают «tring» в «\1». Видимо метод scan в ruby возвращает захваченные значения, и вам кажется что regexp работает по другому.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

liaonau писал(а):
23.02.2011 20:13
Заглядывание вперед надо чтобы ваше регулярное выражение не отхватило лишнего (удостовериться, что впереди что-то есть). А вам же все равно, вы хотите отсечь все кроме первого символа.

ну... что-то есть будет так:
s/(.).+/\1/
если нет ничего, то не сработает. можно и так:
s/^(.)tring$/\1/
причём всё это будет работать в любом ЯП и за один проход. причём реализовано это в glibc, а значит юзаются все процессорные фишки,
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

drBatty писал(а):
23.02.2011 20:36
liaonau писал(а):
23.02.2011 20:13
Заглядывание вперед надо чтобы ваше регулярное выражение не отхватило лишнего (удостовериться, что впереди что-то есть). А вам же все равно, вы хотите отсечь все кроме первого символа.

ну... что-то есть будет так:
s/(.).+/\1/
если нет ничего, то не сработает. можно и так:
s/^(.)tring$/\1/
причём всё это будет работать в любом ЯП и за один проход. причём реализовано это в glibc, а значит юзаются все процессорные фишки,

Это не что-нибудь а что-то (особенное).
Вот пример из Camel Book:

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

$_ = "Paris in the the the the spring.";
#Удалить повторы слов
s/ \b(\w+) \s (?= \1\b ) //gx;

За один проход.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

liaonau писал(а):
23.02.2011 20:49
Вот пример из Camel Book:
Код

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

$_ = "Paris in the the the the spring.";
#Удалить повторы слов
s/ \b(\w+) \s (?= \1\b ) //gx;


За один проход.

сомневаюсь, что это будет ОДИН проход. ИМХО это будет что-то вроде

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

l:
s/\b(\w+)(\s.*\b)\1/\1\2/
tl

в терминах sed.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

drBatty писал(а):
23.02.2011 20:58
сомневаюсь, что это будет ОДИН проход.

Ну, честно говоря, нет. Т.е. будут отдельные запуски машины регулярных выражений для заглядывания вперед, но это будет скрыто от нас. А проход для заданной регулярки будет один. За один regexp без организации нами цикла, точнее что ли сказать?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

liaonau писал(а):
23.02.2011 21:25
Ну, честно говоря, нет. Т.е. будут отдельные запуски машины регулярных выражений для заглядывания вперед, но это будет скрыто от нас. А проход для заданной регулярки будет один. За один regexp без организации нами цикла, точнее что ли сказать?

согласен. но вот что будет быстрее - не знаю. в camelbook'е примерчики конечно быстрее чем в sed, но на практике, ИМХО, часто бывает не так...
мне вообще не попадалось задач, где так уж нужен этот "предпросмотр", и без него никак.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
liaonau
Сообщения: 390
ОС: gentoo

Re: подвыражение в рубби

Сообщение liaonau »

drBatty писал(а):
23.02.2011 21:44
но вот что будет быстрее - не знаю.

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

Собственно речь изначально и шла о том, что, в задаче автора темы, заглядывание бессмысленно.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

liaonau писал(а):
23.02.2011 21:58
Если общее выражение выполняется долго, а то, которое в заглядывании, быстро, то это лучше цикла. А вообще, при современных мощностях, это скорее вопрос предпочитаемой записи.

нет. цикл я вижу. а (?= не вижу. и при тестах это всё отлично работает, но виснет, если скормить какой-нибудь дамп БД в сотни метров, да ещё и в какой-нить vms...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: подвыражение в рубби

Сообщение t.t »

drBatty писал(а):
23.02.2011 21:44
мне вообще не попадалось задач, где так уж нужен этот "предпросмотр", и без него никак.

Мне пару раз попадались. Но учитывая, что последний раз я писал что-то на перле лет пять назад, что это были за задачи, уже не вспомню. Разве только доберусь когда-нибудь до машины со старыми исходниками (и то, если именно те исходники там сохранились).
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: подвыражение в рубби

Сообщение ZyX »

drBatty писал(а):
23.02.2011 19:16
jojahti писал(а):
23.02.2011 18:49
А как тогда поиск по регуляркам делать?

используйте glibc. например через sed. оно быстрее.
Да ну?

/tmp/zsh - 1 (Created by format.vim)

(zyx:~/tmp/app-office:openoffice-3.0.0:20081221-185207.test) % time ( cat app-of fice:openoffice-3.0.0:20081221-185207.log | perl -p -i -e 'undef $_ unless /(\/) [^\/]*$/' >/dev/null ) (; cat app-office:openoffice-3.0.0:20081221-185207.log | perl -p -i -e > ; ) 0 ,62s user 0,01s system 99% cpu 0,638 total (zyx:~/tmp/app-office:openoffice-3.0.0:20081221-185207.test) % time ( cat app-of fice:openoffice-3.0.0:20081221-185207.log | pcregrep '(/)[^/]*$' >/dev/null ) (; cat app-office:openoffice-3.0.0:20081221-185207.log | pcregrep '(/)[^/]*$') 0,43s user 0,02s system 99% cpu 0,453 total (zyx:~/tmp/app-office:openoffice-3.0.0:20081221-185207.test) % time ( cat app-of fice:openoffice-3.0.0:20081221-185207.log | egrep '(/)[^/]*$' >/dev/null ) (; cat app-office:openoffice-3.0.0:20081221-185207.log | egrep '(/)[^/]*$' > ) 50,56s user 0,02s system 99% cpu 50,682 total (zyx:~/tmp/app-office:openoffice-3.0.0:20081221-185207.test) % time ( cat app-of fice:openoffice-3.0.0:20081221-185207.log | grep '\(/\)[^/]*$' >/dev/null ) (; cat app-office:openoffice-3.0.0:20081221-185207.log | grep --color=auto >) 50,03s user 0,14s system 99% cpu 50,266 total (zyx:~/tmp/app-office:openoffice-3.0.0:20081221-185207.test) % time ( cat app-of fice:openoffice-3.0.0:20081221-185207.log | sed '/\(\/\)[^\/]*$/ p' >/dev/null ) (; cat app-office:openoffice-3.0.0:20081221-185207.log | sed > /dev/null; ) 1, 98s user 0,03s system 99% cpu 2,016 total


Всё это дело в таблице:

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

          time  relative
pcregrep  0,43    1
    perl  0,62    1,4
     sed  1,98    4,6
    grep 50,03  116
   egrep 50,56  117
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

t.t писал(а):
23.02.2011 22:59
Мне пару раз попадались

Мне тоже попадались. Поначалу. Но когда я обнаружил, что в некоторых случаях быстродействие обратно пропорционально квадрату средней длинны строки, я уже стал думать... Я уже выше показал, что можно переписать выражение и на sed, только там этот цикл будет записан явно.

ZyX писал(а):
24.02.2011 01:52
Да ну?

1) я вам уже 100500 раз говорил, что для корректности измерений нужно либо заставить sed работать с LC_ALL=C, либо перл заставить работать с utf-8.
2) sed не обрабатывает RE, это всего-лишь удобный интерфейс к libc. откуда мне знать, может ваша libc собранна для i80486, а перл поддерживает последнюю SSE?
3) речь идёт о многопроходовых RE, очевидно, что будучи скомпилированы RE будут выполнятся быстрее, чем в интерпретаторе sed. Потому если задача предполагает предпросмотр, то конечно perl лучше. Но это только на примерах из вашей поваренной книге. На практике это редко нужно.
4) я и не говорил, что "perl не нужен" :)
нужен. просто обратил внимание на то, что обсуждаемые RE на самом деле могут работать очень медленно, и этот глюк проявляется на больших наборах данных, а в тестах незаметен. Предложенный вариант на sed - лишь демонстрация того, что это возможно.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: подвыражение в рубби

Сообщение drBatty »

в догонку:
5) время выполнения и sed и perl скриптов обычно равно 0. их ограничивает скорость чтения файла. а если файл маленький, то время пренебрежимо мало. предпросмотр - как раз тот случай, когда можно заметить жуткие тормоза. независимо от ЯП.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ZyX
Сообщения: 355
ОС: Gentoo

Re: подвыражение в рубби

Сообщение ZyX »

drBatty писал(а):
24.02.2011 10:34
t.t писал(а):
23.02.2011 22:59
Мне пару раз попадались

Мне тоже попадались. Поначалу. Но когда я обнаружил, что в некоторых случаях быстродействие обратно пропорционально квадрату средней длинны строки, я уже стал думать... Я уже выше показал, что можно переписать выражение и на sed, только там этот цикл будет записан явно.

ZyX писал(а):
24.02.2011 01:52
Да ну?

1) я вам уже 100500 раз говорил, что для корректности измерений нужно либо заставить sed работать с LC_ALL=C, либо перл заставить работать с utf-8.

С LANG=C (pcregrep не работает с юникодом) sed таки обгоняет perl (0,53, остальные не изменились), но не обгоняет pcre.
drBatty писал(а):
24.02.2011 10:34
2) sed не обрабатывает RE, это всего-лишь удобный интерфейс к libc. откуда мне знать, может ваша libc собранна для i80486, а перл поддерживает последнюю SSE?
Разумеется, у всех одни флаги компиляции и даже один компилятор: я всегда пересобираю мир после обновления оного.
drBatty писал(а):
24.02.2011 10:34
3) речь идёт о многопроходовых RE, очевидно, что будучи скомпилированы RE будут выполнятся быстрее, чем в интерпретаторе sed. Потому если задача предполагает предпросмотр, то конечно perl лучше. Но это только на примерах из вашей поваренной книге. На практике это редко нужно.
Поэтому лучше брать perl/pcre, так как их синтаксис используется в большем количестве языков. Кроме того, ваше исходное утверждение было, что использование libc, например через sed, быстрее.
drBatty писал(а):
24.02.2011 10:34
4) я и не говорил, что "perl не нужен" :)
нужен. просто обратил внимание на то, что обсуждаемые RE на самом деле могут работать очень медленно, и этот глюк проявляется на больших наборах данных, а в тестах незаметен. Предложенный вариант на sed - лишь демонстрация того, что это возможно.

drBatty писал(а):
24.02.2011 10:41
в догонку:
5) время выполнения и sed и perl скриптов обычно равно 0. их ограничивает скорость чтения файла. а если файл маленький, то время пренебрежимо мало. предпросмотр - как раз тот случай, когда можно заметить жуткие тормоза. независимо от ЯП.

Файл имеет размер 14 МиБ и полностью находился в кэше на момент начала тестирования. Кроме того, если бы это было так, то значимой разницы во времени работы не было бы.

Кстати, проверка с включённым юникодом:
perl: perl -p -i -e 'use open qw(:locale); use utf8; undef $_ unless /(\/)[^\/]*$/'
sed: sed '/\(\/\)[^\/]*$/ p'
python:

Shell

python3 -c $'import sys, re\nr=re.compile(\'(/)[^/]*$\')\nfor line in sys.stdin:\n if r.search(line) is not None:\n print(line[:-1])\n'


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

       time  relative
python 0,88  1
  perl 1,21  1,375
   sed 1,73  1,97


drBatty писал(а):
23.02.2011 21:44
liaonau писал(а):
23.02.2011 21:25
Ну, честно говоря, нет. Т.е. будут отдельные запуски машины регулярных выражений для заглядывания вперед, но это будет скрыто от нас. А проход для заданной регулярки будет один. За один regexp без организации нами цикла, точнее что ли сказать?

согласен. но вот что будет быстрее - не знаю. в camelbook'е примерчики конечно быстрее чем в sed, но на практике, ИМХО, часто бывает не так...
мне вообще не попадалось задач, где так уж нужен этот "предпросмотр", и без него никак.
Относительно необходимости lookahead’ов можно почитать здесь: http://stackoverflow.com/questions/2974210...lar-expressions. Обычно lookahead мною используется либо если надо исключить часть строки из совпадения, либо если надо указать, чем не является некоторый символ. Без первого, в принципе, можно обойтись, а второе проистекает из недостатков регулярных выражений в Vim.
Спасибо сказали: