1

Ruby on Rails 3.2.9 と Ruby 1.9.3 を使用しています。文字列を指定すると、その文字列の末尾にあるすべての /文字を削除したいと思います。つまり、たとえば次のようになります。

From "abc/"   to "abc"
From "abc//"  to "abc"
From "abc///" to "abc"
...
From "a/b/c///" to "a/b/c"

どうすればそれを作成できますか(おそらく正規表現を使用して)?


私は試した:

string = string[0,string.length-1] if string.end_with?('/')

しかし、それは1つのキャラクターに対してのみ機能します。

4

4 に答える 4

5
"abc//".sub %r{/+$}, ''

/これは、文字列の末尾でのみ削除されます。この場合%r{}、エスケープする必要がないため、正規表現を作成するために使用します。/

于 2012-12-26T16:38:36.687 に答える
2

いくつかのベンチマークが整っています。

Perry Horwich の答えは基本的に Huluk の答えと同じなので、同じ結果になると思いました。へー、私は間違っていた。それを見て、正規表現ではなく文字列検索を行っていることに気付いた後、それを修正し、固定テストを追加しました。

その後、何を思いつくことができるかを確認するために、いじくり回しました。私のソリューションは他のソリューションほど単純ではないようですが、最初のソリューションは短い文字列でも同じように高速に動作し、長い文字列ではおそらく少し速くなります。2 番目の 2 つは、短い文字列または長い文字列を処理する場合にはウォッシュですが、どちらも非常に高速です。私は昔ながらの手法に戻り、「昔」にアセンブラーで行っていた方法でそれらを実行しました。

require 'benchmark'

n = 1_000_000

def huluk(s)
  s.sub %r{/+$}, ''
end

def apneadiving1(your_string)
  matches = your_string.match(/(.*?)\/*$/)
  matches[1]
end

def apneadiving2(your_string)
  your_string.scan(/(.*?)\/*$/).flatten.first
end

def fixed_perry_horwich(my_beginning_string)
  my_beginning_string.sub(/\/+$/,'')
end

def the_tin_man1(s)
  s.split(%r[/+$]).first
end

def the_tin_man2(s)
  s = s[0..-2] while s[-1] == '/'
  s
end

def the_tin_man3(s)
  s_len = s.length - 1
  s_len -= 1 while s[s_len] == '/'
  s[0..s_len]
end

puts "Ruby #{ RUBY_VERSION }"
puts "#{ n } iterations"

puts

[
  'abc//',
  'abc' * 50 + '//',
  'abc' * 10 + '////',
  '////////////'
].each do |sample_string|

  puts "sample string: #{ sample_string }"
  puts 'huluk:               %s' % huluk(sample_string)
  puts 'perry_horwich:       %s' % perry_horwich(sample_string)
  puts 'fixed_perry_horwich: %s' % fixed_perry_horwich(sample_string)
  puts 'apneadiving1:        %s' % apneadiving1(sample_string)
  puts 'apneadiving2:        %s' % apneadiving2(sample_string)
  puts 'the_tin_man1:        %s' % the_tin_man1(sample_string)
  puts 'the_tin_man2:        %s' % the_tin_man2(sample_string)
  puts 'the_tin_man3:        %s' % the_tin_man3(sample_string)
  puts

  Benchmark.bm(19) do |b|
    2.times do
      b.report('huluk')               { n.times { huluk(sample_string)               } }
      b.report('fixed_perry_horwich') { n.times { fixed_perry_horwich(sample_string) } }
      b.report('apneadiving1')        { n.times { apneadiving1(sample_string)        } }
      b.report('apneadiving2')        { n.times { apneadiving2(sample_string)        } }
      b.report('the_tin_man1')        { n.times { the_tin_man1(sample_string)        } }
      b.report('the_tin_man2')        { n.times { the_tin_man2(sample_string)        } }
      b.report('the_tin_man3')        { n.times { the_tin_man3(sample_string)        } }
      puts
    end
  end

  puts

end

結果:

ルビー1.9.3
1000000回の繰り返し
サンプル文字列: abc//
フルク: abc
ペリー・ホウィッチ: abc//
fixed_perry_horwich: abc
apneadiving1: abc
apneadiving2: abc
the_tin_man1: abc
the_tin_man2: abc
the_tin_man3: abc

                          ユーザーシステム合計実数
フルク 1.840000 0.000000 1.840000 ( 1.849929)
fixed_perry_horwich 1.840000 0.010000 1.850000 (1.847069)
apneadiving1 1.900000 0.010000 1.910000 ( 1.900817)
apneadiving2 4.860000 0.010000 4.870000 ( 4.883103)
the_tin_man1 1.830000 0.000000 1.830000 ( 1.826547)
the_tin_man2 1.150000 0.000000 1.150000 ( 1.151420)
the_tin_man3 1.170000 0.010000 1.180000 ( 1.168161)

フルク 1.820000 0.000000 1.820000 (1.825440)
fixed_perry_horwich 1.830000 0.000000 1.830000 ( 1.827306)
apneadiving1 1.850000 0.000000 1.850000 ( 1.853751)
apneadiving2 4.830000 0.000000 4.830000 ( 4.825394)
the_tin_man1 1.810000 0.000000 1.810000 ( 1.811503)
the_tin_man2 1.150000 0.000000 1.150000 ( 1.151865)
the_tin_man3 1.170000 0.000000 1.170000 ( 1.172259)
サンプル文字列: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc//
huluk: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
perry_horwich: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc//
fixed_perry_horwich: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
apneadiving1: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
apneadiving2: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
the_tin_man1: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
the_tin_man2: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc
the_tin_man3: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc

                          ユーザーシステム合計実数
フルク 2.120000 0.000000 2.120000 (2.122156)
fixed_perry_horwich 2.130000 0.010000 2.140000 (2.136665)
apneadiving1 9.630000 0.030000 9.660000 ( 9.656817)
apneadiving2 12.420000 0.030000 12.450000 ( 12.459432)
the_tin_man1 2.080000 0.010000 2.090000 ( 2.090112)
the_tin_man2 1.570000 0.010000 1.580000 ( 1.573887)
the_tin_man3 1.380000 0.000000 1.380000 ( 1.388120)

フルク 2.130000 0.010000 2.140000 (2.134414)
fixed_perry_horwich 2.120000 0.010000 2.130000 (2.129399)
apneadiving1 9.620000 0.020000 9.640000 ( 9.646624)
apneadiving2 12.410000 0.020000 12.430000 ( 12.423327)
the_tin_man1 2.080000 0.010000 2.090000 ( 2.090938)
the_tin_man2 1.580000 0.010000 1.590000 ( 1.581131)
the_tin_man3 1.390000 0.000000 1.390000 ( 1.400093)
サンプル文字列: abcabcabcabcabcabcabcabcabcabc////
huluk: abcabcabcabcabcabcabcabcabcabc
perry_horwich: abcabcabcabcabcabcabcabcabcabc////
fixed_perry_horwich: abcabcabcabcabcabcabcabcabcabc
apneadiving1: abcabcabcabcabcabcabcabcabcabc
apneadiving2: abcabcabcabcabcabcabcabcabcabc
the_tin_man1: abcabcabcabcabcabcabcabcabcabc
the_tin_man2: abcabcabcabcabcabcabcabcabcabc
the_tin_man3: abcabcabcabcabcabcabcabcabcabc

                          ユーザーシステム合計実数
フルク 1.980000 0.010000 1.990000 (1.983149)
fixed_perry_horwich 1.970000 0.010000 1.980000 ( 1.979796)
apneadiving1 3.500000 0.010000 3.510000 ( 3.513885)
apneadiving2 6.320000 0.020000 6.340000 ( 6.348327)
the_tin_man1 2.070000 0.010000 2.080000 ( 2.075045)
the_tin_man2 2.800000 0.000000 2.800000 ( 2.801136)
the_tin_man3 1.840000 0.010000 1.850000 ( 1.851506)

フルク 1.980000 0.010000 1.990000 (1.980867)
fixed_perry_horwich 1.980000 0.010000 1.990000 (1.984776)
apneadiving1 3.510000 0.010000 3.520000 ( 3.523383)
apneadiving2 6.340000 0.020000 6.360000 ( 6.357442)
the_tin_man1 2.070000 0.000000 2.070000 ( 2.074559)
the_tin_man2 2.800000 0.010000 2.810000 ( 2.814275)
the_tin_man3 1.850000 0.010000 1.860000 ( 1.855621)
サンプル文字列: ////////////
フルク:               
ペリー・ホウィッチ: ////////////
fixed_perry_horwich:
アプネダイビング1:        
アプネダイビング2:        
the_tin_man1:        
the_tin_man2:        
the_tin_man3:        

                          ユーザーシステム合計実数
フルク 1.980000 0.010000 1.990000 (1.982700)
fixed_perry_horwich 1.980000 0.010000 1.990000 (1.984354)
apneadiving1 1.860000 0.000000 1.860000 ( 1.869155)
apneadiving2 4.840000 0.020000 4.860000 ( 4.852445)
the_tin_man1 2.010000 0.000000 2.010000 ( 2.020292)
the_tin_man2 5.060000 0.020000 5.080000 ( 5.070202)
the_tin_man3 6.390000 0.020000 6.410000 ( 6.412697)

フルク 1.980000 0.010000 1.990000 (1.987652)
fixed_perry_horwich 1.980000 0.010000 1.990000 ( 1.981360)
apneadiving1 1.860000 0.000000 1.860000 ( 1.871577)
apneadiving2 4.850000 0.020000 4.870000 ( 4.857329)
the_tin_man1 2.010000 0.010000 2.020000 ( 2.023877)
the_tin_man2 5.060000 0.010000 5.070000 ( 5.067753)
the_tin_man3 6.410000 0.020000 6.430000 ( 6.434523)

提示されたパターンとアルゴリズムに敵対するために、単純なケースと"abc//"、152 文字の「悪いケース」と見なすものを区別しようとしました。

hulukソースがRubyによって解釈されるとfixed_perry_horwich、それらの違いがコンパイルされてしまうためです。


編集:

いくつかの変更:

  • コードをリファクタリングして DRY にしました。
  • perry_horwichテストする意味がなかったので、ベンチマークからテストを削除しました。
  • '////////////'@pguardiario の推奨でテストを追加しました。これは、区切り文字を取り除いた最悪のケースのテストの結果を示しています。

テスト結果から得られるのは、テストされるデータの種類を見て、入力に最適なアルゴリズムを選択することです。一部の入力でうまく機能するものが、他の入力でもうまく機能するとは限りません。「昔ながらの」方法が、短い末尾区切り文字列に正規表現を使用するソリューションよりも優れていることは興味深いことでした。これは、Ruby がコンパイル済みコードへの呼び出しを設定した結果だと思います。区切り文字列が長くなると、コンパイルされたコードが有利になります。

于 2012-12-26T18:56:00.327 に答える
1

正規表現を使用して、文字列の予期される部分を取得します。

/(.*?)\/*$/

Rubularを参照してください。

reg = /(.*?)\/*$/
matches = your_string.match(reg)
result = matches[1] 

#or
result = your_string.scan(reg).flatten.first
于 2012-12-26T16:38:54.780 に答える
0

これはあなたの例でうまくいきます:

my_no_slash_terminated_string = my_beginning_string.sub(/\/+$/,'')

文字列の末尾または末尾近くの空白も考慮する必要があるかどうかを検討してください。

于 2012-12-26T16:48:32.357 に答える