Подтвердить что ты не робот

Ruby сокращает все пробелы до отдельных пробелов

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

1/2 cup  




            onion           
             (chopped)

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

4b9b3361

Ответ 1

Это случай, когда регулярные выражения работают хорошо, потому что вы хотите обрабатывать весь класс символов пробелов одинаково и заменять пробелы любой комбинации пробелов одним символом пробела. Поэтому, если эта строка хранится в s, вы должны:

fixed_string = s.gsub(/\s+/, ' ')

Ответ 2

В Rails вы можете использовать String#squish, который является расширениями active_support.

require 'active_support'

s = <<-EOS
1/2 cup  

            onion
EOS

s.squish
# => 1/2 cup onion

Ответ 3

Вам нужен метод сжатия:

str.squeeze([other_str]*) → new_str
Builds a set of characters from the other_str parameter(s) using the procedure described for String#count. Returns a new string where runs of the same character that occur in this set are replaced by a single character. If no arguments are given, all runs of identical characters are replaced by a single character.

   "yellow moon".squeeze                  #=> "yelow mon"
   "  now   is  the".squeeze(" ")         #=> " now is the"
   "putters shoot balls".squeeze("m-z")   #=> "puters shot balls"

Ответ 4

Проблема с простейшим решением gsub(/\s+/, ' ') заключается в том, что она очень медленная, поскольку она заменяет любое пространство, даже если оно одно. Но обычно между словами есть 1 пробел, и мы должны исправить только в том случае, если в последовательности есть 2 или более пробелов.

Лучшее решение gsub(/[\r\n\t]/, ' ').gsub(/ {2,}/, ' ') - сначала избавиться от специальных пробелов, а затем сжать нормальные пробелы

def method1(s) s.gsub!(/\s+/, ' '); s end
def method2(s) s.gsub!(/[\r\n\t]/, ' '); s.gsub!(/ {2,}/, ' '); s end

Benchmark.bm do |x|
  n = 100_000
  x.report('method1') { n.times { method1("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('method2') { n.times { method2("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
end;1

#        user     system      total        real
# method1  4.090000   0.010000   4.100000 (  4.124844)
# method2  1.590000   0.010000   1.600000 (  1.611443)

Ответ 5

Выбранный ответ не удаляет символы non-break space.

Это должно работать в версии 1.9:

fixed_string = s.gsub(/(\s|\u00A0)+/, ' ')

Ответ 6

Если скорость вызывает беспокойство, тогда Лев ответит на ваш лучший выбор.

.gsub(/[\r\n\t]/, ' ').gsub(/ {2,}/, ' ')

Я увидел тест, который отправил Лев, и удивился, как .gsub! .gsub.sqeeze и .squish по сравнению. Я расширил его тест, чтобы проверить их все, и, хотя .squeeze - самый быстрый, он не отвечает на вопросы, поскольку он будет сжимать только несколько вкладок/новые строки в одну вкладку/новую строку.

# Replace multiple whitespace characters with a single space.
def method1(s) s.gsub!(/\s+/, ' '); s end # (in place)         
def method2(s) s = s.gsub(/\s+/, ' '); s end

# Replace any white space character with a space then replace multiple spaces with a single space (in place).
def method3(s) s.gsub!(/[\r\n\t]/, ' '); s.gsub!(/ {2,}/, ' '); s end # (in place) 
def method4(s) s = s.gsub(/[\r\n\t]/, ' '); s = s.gsub(/ {2,}/, ' '); s end

# Replace multiple whitespace characters with a single space.
def method5(s) s.squish!; s end # (in place) 
def method6(s) s = s.squish; s end

# Combines multiple spaces into a single space
def method7(s) s.squeeze!(" "); s end # (in place) 
def method8(s) s = s.squeeze(" "); s end

Benchmark.bm do |x|
  n = 100_000
  x.report('.gsub!      ') { n.times { method1("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.gsub       ') { n.times { method2("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.gsub!.gsub!') { n.times { method3("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.gsub.gsub  ') { n.times { method4("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.squish!    ') { n.times { method5("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.squish     ') { n.times { method6("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.squeeze!   ') { n.times { method7("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
  x.report('.squeeze    ') { n.times { method8("Lorem   ipsum\n\n dolor \t\t\tsit amet, consectetur\n \n\t\n adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") } }
end

#=>
#               user       system     total       real
# .gsub!        2.115536   0.033067   2.148603 (  2.157457)
# .gsub         2.021564   0.008644   2.030208 (  2.041524)
# .gsub!.gsub!  0.871203   0.015546   0.886749 (  0.890107)
# .gsub.gsub    0.816160   0.007435   0.823595 (  0.827268)
# .squish!      2.052532   0.007074   2.059606 (  2.066196)
# .squish       2.092860   0.007376   2.100236 (  2.107255)
# .squeeze!     0.128961   0.002661   0.131622 (  0.132495)
# .squeeze      0.204354   0.007207   0.211561 (  0.212284)