Ruby сокращает все пробелы до одиночных пробелов - PullRequest
29 голосов
/ 11 января 2011

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

1/2 cup  




            onion           
             (chopped)

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

Ответы [ 6 ]

61 голосов
/ 11 января 2011

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

fixed_string = s.gsub(/\s+/, ' ')
18 голосов
/ 26 октября 2016

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

require 'active_support'

s = <<-EOS
1/2 cup  

            onion
EOS

s.squish
# => 1/2 cup onion
9 голосов
/ 11 января 2011

Вы хотите метод сжатия:

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"
6 голосов
/ 16 февраля 2016

Проблема с самым простым решением 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)
4 голосов
/ 28 января 2013

Выбранный ответ не удалит неразрывный пробел символов.

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

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

0 голосов
/ 06 февраля 2019

Если скорость имеет значение, то лучше всего ставить вот что.

.tr("\r\n\t", ' ').gsub(/ {2,}/, ' ')

Это заменяет пробельные символы пробелом, а затем заменяет несколько пробелов одним пробелом.

Я видел бенчмарк, который выложил Лев, и сравнил варианты gsub .sqeeze .tr и .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 characters with a space then replace multiple spaces with a single space.
def method3(s) s.gsub!(/[\r\n\t]/, ' '); s.gsub!(/ {2,}/, ' '); s end # (in place)
def method4(s) s = s.gsub(/[\r\n\t]/, ' ').gsub(/ {2,}/, ' '); s end

# Replace characters with a space then replace multiple spaces with a single space.
def method5(s) s.tr!("\r\n\t", ' '); s.gsub!(/ {2,}/, ' '); s end # (in place)
def method6(s) s = s.tr("\r\n\t", ' ').gsub(/ {2,}/, ' '); s end

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

# Combines multiple spaces into a single space
def method9(s) s.squeeze!(" "); s end # (in place)
def method10(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('.tr!.gsub!  ') { 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('.tr .gsub   ') { 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('.squish     ') { 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('.squish!    ') { 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.") } }
  x.report('.squeeze!   ') { n.times { method9("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 { method10("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.019544   0.030325   2.049869 (  2.059379)
# .gsub         1.968179   0.011204   1.979383 (  1.988050)
# .gsub!.gsub!  0.770042   0.014097   0.784139 (  0.787055)
# .gsub .gsub   0.728955   0.011577   0.740532 (  0.742887)
# .tr!.gsub!    0.487014   0.008260   0.495274 (  0.496820)
# .tr .gsub     0.487231   0.007769   0.495000 (  0.497164)
# .squish!      2.005224   0.011673   2.016897 (  2.025851)
# .squish       2.043497   0.013331   2.056828 (  2.066794)
# .squeeze!     0.117615   0.002004   0.119619 (  0.120140)
# .squeeze      0.196301   0.012094   0.208395 (  0.209267)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...