Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Ruby: Общие вопросы > Работа с рег. выражениями


Автор: prog2 7.1.2008, 16:42
Знаком с руби очень мало. В универе дали задания все решил, только вот с одним проблема. Дан URL-адрес, требуется вывести только домен. Сделать это нужно макс 20-25 символов, т.е с использованием рег выражений. Бился над этой задачей очень долго и не смог ее одолеть. Помогите пож-та. Заранее благодарен. 

Если это возможно сделать без рег. выражений - тоже можно главное чтобы длина программы была как можно короткой

Автор: source777 7.1.2008, 17:10
Так сойдёт?
Код

  url="http://forum.vingrad.ru/forum/topic-190317.html";
  print url.sub(/.*?\/{2}(.*?)(\/|$).*/, '\1');


Добавлено через 8 минут и 52 секунды
Или ещё компактнее:
Код

  url="http://forum.vingrad.ru/forum/topic-190317.html";
  print url.scan(/\/\/([^\/]*)/);

Автор: prog2 7.1.2008, 17:46
А так что бы на выходе было не forum.vingrad.ru , а vingrad.ru

Автор: source777 7.1.2008, 20:04
Цитата

А так что бы на выходе было не forum.vingrad.ru , а vingrad.ru 

Так тоже можно, только 20-25 символов у тебя лимит на весь(вместе с print url.) код или эксклюзивно для регулярного выражения? А то один регэксп уже 31 символ занимает, а сокращать его особо некуда...
Код

  print url.sub(/.*?\\/\\/([^\\/]*?\\.)+([^\\/]*).*/, \'\\1\\2\'); # vingrad.ru


Добавлено через 11 минут и 9 секунд
На вдогонку вариант для scan
Код

  print url.scan(/\\/\\/([^\\/]*?\\.)+([^\\/]*)/); # vingrad.ru

Автор: prog2 7.1.2008, 22:20
Цитата(source777 @ 7.1.2008,  20:04)
Цитата

А так что бы на выходе было не forum.vingrad.ru , а vingrad.ru 

Так тоже можно, только 20-25 символов у тебя лимит на весь(вместе с print url.) код или эксклюзивно для регулярного выражения? А то один регэксп уже 31 символ занимает, а сокращать его особо некуда...
Код

  print url.sub(/.*?\\/\\/([^\\/]*?\\.)+([^\\/]*).*/, \'\\1\\2\'); # vingrad.ru


Добавлено @ 20:15
На вдогонку вариант для scan
Код

  print url.scan(/\\/\\/([^\\/]*?\\.)+([^\\/]*)/); # vingrad.ru

Выдает ошибку:
C:/ruby/bin/1.rb:2: warning: regexp has `]' without escape
C:/ruby/bin/1.rb:2: unmatched ): /]*?\\.)+([^\\/
C:/ruby/bin/1.rb:2: parse error, unexpected ']', expecting ')'

Добавлено через 10 минут и 57 секунд
Лимит без учета print url

Автор: source777 7.1.2008, 22:53
Цитата

Выдает ошибку:
C:/ruby/bin/1.rb:2: warning: regexp has `]\' without escape
C:/ruby/bin/1.rb:2: unmatched ): /]*?\\\\.)+([^\\\\/
C:/ruby/bin/1.rb:2: parse error, unexpected \']\', expecting \')\'

Ну ты сам то совсем в регэкспах не разбираешься что ли? это форум что-то обратный слеш продубрировал везде с какого-то перепугу...
Код

  print url.scan(/\\/\\/([^\\/]*?\\.)+([^\\/]*)/); 

24 символа без учёта границ получается...

Добавлено через 1 минуту и 32 секунды
Блин, опять обратный слеш дублируется... 

P.S. Модераторы ау, обратите внимание на баг...

Автор: prog2 8.1.2008, 19:45
А по-другому как то можно эту задачу решить. Без регулярных выражений. Просто последний вариант то же не подходит. Это должно работать для любых URL адресов

Автор: tek 11.1.2008, 00:24
Мой вариант :
Код


url = 'http://blah.site.ru/fasd?fa=222.php'
p $1 if url =~ /\/\/(.*?)\// 



результат : blah.site.ru

Вырезать site.ru - можно, но в вашем случае врятле кто-то напишет универсальный регексп, который будет всегда вытягивать "site.ru"
тем более в 25 символов.
Вдруг там -  www.yyy.zzz.ok.cz или http://www.xxx.yyy.ZZZ.NET.RU - а вам нужно "ZZZ.NET.RU".

Автор: shine 11.1.2008, 11:40
На самом деле все проще:
Код

puts url.scan(/\/\/.*\.(.*\..*?)\//)

21 символ
hint: ищем последнее минимальное вхождение последовательности символы+точка+символы между двумя слэшами и одним

Автор: source777 11.1.2008, 21:12
shine, твой пример тоже не сработает верно на http://www.xxx.yyy.ZZZ.NET.RU (с) tek и даже на http://vingrad.ru тоже не сработает ;) корректную реализацию модернизированной идеи, которую ты описал в хинте можно увидеть в моём посте чуть выше(она там 24 символа заняла)

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

Автор: prog2 13.1.2008, 01:44
Всем спасибо! Помогло - 
Код

puts url.scan(/\/\/.*\.(.*\..*?)\//) (с) shine

Автор: tek 13.1.2008, 12:57
prog2, хоршо конечно что вам помогло, но тема сисек не раскрыта  smile 

Не работат же пример shine если зона - net.ru, org.cn и т.п.

 smile 

Автор: source777 13.1.2008, 16:16
Цитата

Не работат же пример shine если зона - net.ru, org.cn и т.п.
да, он вообще не работает, если одиночного слеша в URL нет...
И вопрос к prog2, почему тогда мой вариант, работающий для более широкого класса допустимых URL, тебе не подошёл?

Автор: shine 13.1.2008, 18:05
Цитата(tek @ 13.1.2008,  12:57)
prog2, хоршо конечно что вам помогло, но тема сисек не раскрыта  smile 

Не работат же пример shine если зона - net.ru, org.cn и т.п.

 smile

Так а я и не прошу мне давать медаль 'за раскрытие сисек' smile
Твой вариант не будет работать если в url входит поддомен  smile 

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

Автор: 130 24.1.2008, 00:50
Вот так короче всего smile

Код

link = 'http://forum.vingrad.ru/forum/ruby-basics.html'
URI( link ).host #=> "forum.vingrad.ru"


Или:

Код

link = 'http://forum.vingrad.ru/forum/ruby-basics.html'
URI( link ).host.split( '.' ).last( 2 ).join( '.' ) #=> "vingrad.ru"


Автор: nilich 24.5.2008, 16:05
Тут возник вопрос, как с помощью регулярных выражений и scan'а вырезать из такой строки:
<tr><td>11111111</td></tr><tr><td>22222222</td></tr>
вырезать все то, что между <tr></tr>
т.е. на выходе получаем:
["<td>11111111</td>","<td>22222222</td>"]

Автор: kemiisto 24.5.2008, 23:38
nilich, вот так, например:
Код

s = "<tr><td>11111111</td></tr><tr><td>22222222</td></tr>"
s.scan(/(<tr>)(.*)(<\/tr>)/) {puts $2}

Автор: shine 25.5.2008, 07:03
Цитата(nilich @ 24.5.2008,  16:05)
с помощью регулярных выражений и scan'а

лучше возьмите gem hpricot и не мучайтесь. там все это уже изобретено

Автор: nilich 25.5.2008, 12:51
kemiisto
если следовать твоему совету то на выходе получим:
<td>11111111</td></tr><tr><td>22222222</td>
Что не есть то, что мне надо smile 

Автор: kemiisto 25.5.2008, 13:22
nilich, извиняюсь! Неучёл "жадность" квантификатора! Должно быть так:
Код

s = "<tr><td>11111111</td></tr><tr><td>22222222</td></tr>"
s.scan(/(<tr>)(.*?)(<\/tr>)/) {puts $2}


Автор: v2v 25.5.2008, 17:16
http://www.rubular.com/
ещё и на руби smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)