Ответ 1
@sawa Простой ответ, и вы отредактировали свой вопрос другим механизмом. Однако, чтобы ответить на два из ваших вопросов:
Есть ли способ сделать это в регулярном выражении?
Нет, Ruby regex не поддерживает функцию изменения регистра, как некоторые другие варианты regex. Вы можете "доказать" это себе, просмотрев официальные документы регулярного выражения Ruby для 1.9 и 2.0 и поиская слово "случай":
- https://github.com/ruby/ruby/blob/ruby_1_9_3/doc/re.rdoc
- https://github.com/ruby/ruby/blob/ruby_2_0_0/doc/re.rdoc
Я действительно не понимаю вещь '\ 1' '\ 2'. Это обратная связь? Как это работает?
Ваше использование \1
- это своего рода обратная связь. Если вы используете \1
и т.д. В шаблоне поиска, может быть обратная ссылка. Например, регулярное выражение /f(.)\1/
найдет букву f
, за которой следует любой символ, за которым следует тот же самый символ (например, "foo" или "f!!" ).
В этом случае в заменяющей строке, переданной методу типа String#gsub
, обратная ссылка относится к предыдущему захвату. Из документов:
"Если замена является строкой, она будет заменена совпадающим текстом. Она может содержать обратные ссылки на группы захвата шаблонов формы
\d
, гдеd
- номер группы или\k<n>
, гдеn
- это имя группы. Если это строка с двумя кавычками, обе обратные ссылки должны предшествовать дополнительной обратной косой чертой."
На практике это означает:
"hello world".gsub( /([aeiou])/, '_\1_' ) #=> "h_e_ll_o_ w_o_rld"
"hello world".gsub( /([aeiou])/, "_\1_" ) #=> "h_\u0001_ll_\u0001_ w_\u0001_rld"
"hello world".gsub( /([aeiou])/, "_\\1_" ) #=> "h_e_ll_o_ w_o_rld"
Теперь вам нужно понять, когда выполняется код. В вашем исходном коде...
string.gsub!(/([a-z])([A-Z]+ )/, '\1'.upcase)
... то, что вы делаете, вызывает upcase
в строке '\1'
(которая не имеет никакого эффекта), а затем вызывает метод gsub!
, передавая в регулярное выражение и строку в качестве параметров.
Наконец, еще один способ достижения этой же цели состоит в том, что блочная форма выглядит так:
# Take your pick of which you prefer:
string.gsub!(/([a-z])([A-Z]+ )/){ $1.upcase << $2.downcase }
string.gsub!(/([a-z])([A-Z]+ )/){ [$1.upcase,$2.downcase].join }
string.gsub!(/([a-z])([A-Z]+ )/){ "#{$1.upcase}#{$2.downcase}" }
В блочной форме gsub захваченные шаблоны устанавливаются на глобальные переменные $1
, $2
и т.д., и вы можете использовать их для построения строки замены.