Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как измененить все фрагменты найденные регуляркой? Заменить все символы, которые не тэги. 
:(
    Опции темы
Bose
  Дата 23.10.2009, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: нет
Всего: 51



Скажу сразу, с Руби столкнулся всего пару дней назад и не по велению души, а по необходимости. 

Задача, по-видимому, тривиальная.

Дано: на входе строка(содержащая в себе фрагмент html). 
Нужно заменить все упоминания текста "а" на "@", не изменяя html-тэги.

Например, есть текст:
Код

<div class="wiki"> 
  <h1 id="Header1">Header1<a href="#Compile" class="wiki-anchor">&para;</a></h1> 
    <h2 id="Header2">Header 2<a href="#Compiler-directives" class="wiki-anchor">&para;</a></h2> 
    <p>Some another text;</p> 
    <p><a href="http://www.example.com">another link</a></p> 
</div> 


Нужно чтобы замена произошла только в тексте, не изменяя тэги. Т.е. чтобы
Header 1 => He@der 1
Header 2 => He@der 2
Some another text; -> Some @nother text;
another link -> @nother link

Как такое сделать правильно (желательно стандартными средствами Ruby + Rails + регулярки)?
PM MAIL WWW Skype   Вверх
source777
Дата 25.10.2009, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(Bose @  23.10.2009,  16:44 Найти цитируемый пост)
Задача, по-видимому, тривиальная.

Задача вообще-то довольно сложная, если решать её одним регулярным выражением. 
Но в Ruby решается довольно просто, т.к. gsub может принимать блок:
Код

  puts text.gsub(/>.*?</) { |m| m.gsub('a', '@') }

На выходе:
Цитата

<div class="wiki"> 
  <h1 id="Header1">He@der1<a href="#Compile" class="wiki-anchor">&p@r@;</a></h1> 
    <h2 id="Header2">He@der 2<a href="#Compiler-directives" class="wiki-anchor">&p@r@;</a></h2> 
    <p>Some @nother text;</p> 
    <p><a href="http://www.example.com">@nother link</a></p> 
</div>



--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
Bose
Дата 26.10.2009, 02:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: нет
Всего: 51



source777, спасибо за ответ. Он мне действительно помог.

Я не очень точно сформулировал задачу.  
Это необязательно должно быть регулярное выражение. Просто насколько я понимаю, с регулярками такое сделать проще всего.

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

Пока что я сделал так (признаюсь, что большая часть кода - это copy&paste, и некоторых вещей я ещё не понимаю. Например - зачем нужна собачка перед @my_rules):
Код

    MY_RULES = [['redmine','"redmine":http://www.redmine.org'],['radio','[[radio]]']]
    def inline_my( text )
       @my_rules = MY_RULES.collect do |my_rule|
         text.gsub!(/>.*?</) { |m| m.gsub( my_rule[0], my_rule[1]) }
       end.flatten
     end


Правила по замене у меня пока хранятся в массиве. (когда научусь , я их буду загружать из БД). 

По ходу тестирования появились ещё 2 вопроса:
1) Не будет ли эффективнее поменять циклы замены местами? Чтобы сначала происходил поиск текста по />.*?</ а уже потом, цикл по элементам массива? Если да, то как такое сделать? smile
2) Как сделать, чтобы поиск текста из my_rule[0] был нечувствительным к РеГистру? (case insensitive)? 

Избавится от чувствительности к Регистру я смог, только заменив текст в массиве с
'redmin' на /redmine/i
но это мне кажется неудобным. Есть ли какой способ добавить опцию /i на лету? Или отключить чувствительность к регистру только для этой замены (не глобально)?
Код

    MY_RULES = [[/redmine/i,'"redmine":http://www.redmine.org'],['radio','[[radio]]']]


PM MAIL WWW Skype   Вверх
source777
Дата 26.10.2009, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1878
Регистрация: 12.3.2007

Репутация: 6
Всего: 56



Цитата(Bose @  26.10.2009,  02:25 Найти цитируемый пост)
Как сделать, чтобы поиск текста из my_rule[0] был нечувствительным к РеГистру? (case insensitive)? 

gsub может принимать для поиска как строку, так и регулярное выражение:
Код

  rules = {'redmine' => '"redmine":http://www.redmine.org', 'radio' => '[[radio]]'}
  rules.each do |term, replacement|
    text.gsub!(/>.*?</) { |m| m.gsub(/#{term}/i, replacement) }
  end


Цитата(Bose @  26.10.2009,  02:25 Найти цитируемый пост)
Не будет ли эффективнее поменять циклы замены местами? 

Возможно и будет, benchmark тебе в помощь. 
Несколько замен можно сделать прямо в блоке, передаваемом gsub, главное чтобы блок возвращал итоговый результат.





--------------------
Если бы программистам платили за то, чтобы убирать код из программы вместо того, чтобы добавлять его, программы были бы намного лучше © Николас Негропонте
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Ruby: Общие вопросы"
source777
  • С чего начать? начинаем
  • Ссылки на полезные ресурсы смотрим тут
  • Обязательно следуйте правилам Vingrad.
  • Пожалуйста, прочитайте рекомендации по работе в форуме и навигации по Vingrad.
  • Для вставки кодов Ruby используйте тег: [code=ruby]код[/code]. Когда в будущем подсветка синтаксиса для Ruby будет реализована, весь исходных код преобразится.
  • Используйтe чекбокс "Транслит" (возле кнопок кодов), если у Вас нет русских шрифтов.
  • Помните, для каждого вопроса должна быть своя тема.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, source777.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Ruby: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0778 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.