2012-02-02 2 views
1

проблему регулярных выражений в рубин, и по какой-то причине, мне это нужно в одна линия в методе GSUB рубинаRegex заменить подстроку вхождения * только *, когда они заключены между начала/конца скобки

Пусть вход sample переменной строка многострочные строк, как показано ниже

begin1 item abc item abc item 
extra end1 
begin2 item abc item abc extra end2 
begin1 item abc item abc extra end1 

правила изменить все item, которые внутри блок begin1 и end1 в love, он может через несколько линий

После замены, выход sample должен быть

begin1 love abc love abc love 
extra end1 
begin2 item abc item abc extra end2 
begin1 love abc love abc love end1 

решение что-то вроде этого

puts sample.gsub!(/(begin1.*)item*(.*end1)/m,'\1love\2') 

ответ

3

Как насчет этого: sample.gsub!(/item(?=((?!begin1).)*end1)/m, 'love')?

И, чтобы сделать регулярное выражение немного меньше магии:

/ 
    item    
    (?=    # look-ahead assertion 
    (    
     (?!begin1) # negative look-ahead assertion 
     .    # any character that is not part of the 'begin1' sequence 
    )*    # there's no 'begin1' after 'item' and before 'end1' 
    end1   # there is 'end1' after 'item' 
) 
/mx     # /m - for multiline strings, x - for comments 

(обрати внимание, что он будет правильно работать, только если «разметка» является «правильной» - например, нет никаких задних концов или ведущих начинается, нет гнездовых блоков)

Кроме того, я не могу сказать, что регулярные выражения являются плохим инструментом для такой задачи. Сложные регулярные выражения слишком непонятны и слишком недостижимы, они похожи на черную магию - вы никогда не знаете, когда они рухнут :)

+0

Итак, магия, и она работает именно то, что я хочу. И он отлично работает для малого ввода, когда он идет большим, он сообщает 'Переполнение стека в матче регулярного выражения' –

+0

Ответ достаточно хорош,' переполнение стека 'связано только с ruby ​​1.8.7, решение отлично работает в 1,9. спасибо alexis. см. реальный скрипт https://github.com/larrycai/sdcamp/commit/923237e5c –

+0

@larrycai Я только что протестировал его в ruby ​​1.8.7 - он работал для меня просто отлично ... – Alexis

0

Я не совсем уверен, что вы имеете в виду с входной части вашего вопроса, поэтому я Я немного смущен, но я думаю, что вы используете метод gsub неправильно. Попробуйте следующее:

> string = 'begin1 item abc item abc item' 
=> "begin1 item abc item abc item" 
> string.gsub(/item/, 'love') 
=> "begin1 love abc love abc love" 

Это простой метод замещения обычного выражения. Read the docs for more details on how to use it. Я думаю, вы можете сделать его более сложным, чем это должно быть.

+0

Я обновляю вопрос. Ввод представляет собой строку с несколькими строками и изменение 'item' между' begin1' и 'end1' на' love' в одной строке –

Смежные вопросы