2017-02-17 10 views
1

У меня есть следующие строки:Regex: Как заменить все символы, кроме слова/последовательности рисунка?

"ft-2 MY AWESOME ft-12 APP" 
"MY AWESOME APP" 
"MY AWESOME APP ft-20" 

Я хочу сделать некоторые изменения (titleization в данном случае) на словах, за исключением ft-<NUMBER> частей. ft-<NUMBER> Слово может появляться в любом месте. Он может появляться несколько раз или вообще не может присутствовать. После манипуляций со строками, конечные результаты должны выглядеть следующим образом:

"ft-2 My Awesome ft-12 App" 
"My Awesome App" 
"My Awesome App ft-20" 

Можно ли писать регулярное выражение в Ruby, который может сделать это преобразование?

Я пытался так:

"ft-4 MY AWESOME ft-5 APP".gsub(/(?<=ft-\d\s).*/) { |s| s.titleize } 

Я получил это: ft-4 My Awesome Ft 5 App взамен.

+0

Вы еще что-нибудь пробовали? –

+0

Я пробовал с 'gsub', но я не мог понять, чтобы соответствовать всем символам, кроме шаблона. – Musaffa

+0

Пожалуйста, разместите код, который вы пробовали. –

ответ

1

Вашего (?<=ft-\d\s).* шаблон соответствует любому месту, начинающееся с ft-<digits><whitespace>, а затем соответствует любому 0+, кроме разрыва строки символов, которые вы titleize символов.

Вы должны соответствовать целым целям, которые не начинаются с ft-<NUMBER> pattern.Тогда все, что вам нужно, это downcase матч и капитализировать его:

s.gsub(/\b(?!ft-\d)\p{L}+/) { | m | m.capitalize } 

Или, если вы предпочитаете использовать $1 переменную, добавьте захвата группы:

s.gsub(/\b(?!ft-\d)(\p{L}+)/) { $1.capitalize } 

Смотрите Ruby demo

Данные по рисунка:

  • \b - прежде всего, отстаивать позицию перед буквой (потому что следующая модель потребляющих является \p{L}, что соответствует письмо)
  • (?!ft-\d) - отрицательный предпросмотр, который не матч, если в ближайшие 2 буквы ft, которые следуют с - и цифра
  • (\p{L}+) - это группа записи соответствия 1+ письма (что далее по тексту с $1 в блоке замены)

capitalize«возвращает копию ул с первого символа преобразуется в верхний регистр, а остаток - в нижний регистр ".

+0

Можно ли оставить остальное в качестве предложения вместо отдельных слов с '\ b'? 'titleize' gem обрабатывает небольшие слова типа and, of, in и т. д., если они находятся в середине предложения. Для «ft-5 MY AWESOME APP RAILS ft-20», я хочу получить «ft-5 My Awesome App of Rails ft-20». Здесь 'of' обрабатывается драгоценным камнем заголовка, если он находится в середине набора слов. – Musaffa

+0

Вам нужно будет обрабатывать их в негативном свете, боюсь. Подобно '\ b (?! Ft- \ d | (?: Off? | In (?: To)? | At) \ b)' –

0

Я не 100% уверен, что вы хотите, но я думаю, что то, что вы хотите, чтобы downcase, а затем titleize строки

У меня есть что-то подобное на одном из моих проектов

#lib/core_ext/string.rb 
class String 
    def my_titleize 
    humanize.gsub(/\b('?[a-z])/) { $1.capitalize } 
    end 
end 

humanize (options = {}) public Капитализует первое слово, поворачивает подчеркивает пробелы и разбивает конечный «_id», если он присутствует. Подобно titleize, это предназначено для создания довольно вывода.

Капитализацию первого слова можно отключить, установив опционный параметр в значение false. По умолчанию этот параметр равен true.

+0

Ruby 'String' не имеет метода' humanize'. – mudasobwa

4
R =/
    [[:alpha:]]+ # match one or more uppercase or lowercase letters 
    (?=\s|\z) # match a whitespace or end of string (positive lookahead) 
    /x   # free-spacing regex definition mode 

def doit(str) 
    str.gsub(R) { |s| s.capitalize } 
end 

doit "ft-2 MY AWESOME ft-12 APP" 
    #=> "ft-2 My Awesome ft-12 App" 
doit "MY AWESOME APP" 
    #=> "My Awesome App" 
doit "MY AWESOME APP ft-20" 
    #=> "My Awesome App ft-20"