루비, 문자열에서 마지막 N자를 제거 하시겠습니까?


답변:


36

루비 2.5 이상

Ruby 2.5부터는 빠르고 읽기 쉬운 방식으로이를 사용 delete_suffix하거나 delete_suffix!달성 할 수 있습니다 .

방법에 대한 문서는 여기에 있습니다 .

접미사가 무엇인지 아는 경우, 이것은 관용적입니다 (그리고 다른 답변보다 훨씬 읽기 쉽습니다).

'abc123'.delete_suffix('123')     # => "abc"
'abc123'.delete_suffix!('123')    # => "abc"

최고 답변보다 훨씬 빠릅니다 ( 뱅 방법 의 경우 거의 40 % ). 동일한 벤치 마크의 결과는 다음과 같습니다.

                     user     system      total        real
chomp            0.949823   0.001025   0.950848 (  0.951941)
range            1.874237   0.001472   1.875709 (  1.876820)
delete_suffix    0.721699   0.000945   0.722644 (  0.723410)
delete_suffix!   0.650042   0.000714   0.650756 (  0.651332)

이 방법이 유용하기를 바랍니다.이 방법은 현재 정규 표현식을 허용하지 않으므로 접미사를 모르면 당분간 실행되지 않습니다. 그러나 받아 들여진 대답 ( 업데이트 : 작성 시점 )이 똑같이 지시하기 때문에 이것이 일부 사람들에게 유용 할 것이라고 생각했습니다.


1
@JPSilvashy 나는 체크 표시를 잃는 것을 더 기쁘게 생각하지 않았습니다. 이것은 좋은 대답입니다.
Wayne Conrad

1
이것은 훌륭하고 빠른 기능이지만 정확한 질문이 아니기 때문에 정답은 아닙니다.What is the preferred way of removing the last n characters from a string?
Sam

1
의견 @Sam에 감사드립니다-이 질문은 거의 9 년 동안이 질문과 동일한 효과를 보였으며 글을 쓸 때 261 개의 공감대가있었습니다. JP는 그것을 받아 들여 최근에 이것을 전환했기 때문에 그들의 질문에 대답했다고 말했습니다 . 사실, 나는이 질문 에이 모든 것을 다뤘습니다.이 방법이 곧 정규 표현식을 받아들이기를 바랍니다. 그러나 바로 아래에 귀하의 경우를위한 완벽한 대안이 있습니다.
SRack September

316
irb> 'now is the time'[0...-4]
=> "now is the "

9
이것은 Ruby 1.9에서만 작동합니다. Ruby 1.8에서는 마지막 문자가 아닌 마지막 바이트 를 제거합니다 .
Jörg W Mittag

2
그러나 1.8.x를 사용하는 경우 "바이트"를 의미했을 것입니다.
DigitalRoss

4
이것은 작동하지만 짧고 긴 문자열 모두에서 'abc123'.chomp ('123 ')이 두 배 빠릅니다. (Ruby 2.0.0-p247) 누구든지 이것을 확인할 수 있습니까?
Plasmarob

10
이 특정 예제하지 않는 이유를 궁금해 사람들을 위해 3 점 work..there되지는 않습니다이 즉 [0...-4]없습니다[0..-4]
rorofromfrance

2
@Plamarob 나는 chomp가 두 배 빠르다는 것보다 53 나노초 빠르다는 것이 더 관련이 있다고 생각합니다. 그러면 비용 대비 사용 가치, 주어진 상황에서 최적화해야하는지 여부를 더 잘 추정 할 수 있습니다.
cesoid 2016 년

266

제거하려는 문자가 항상 같은 문자이면 다음을 고려하십시오 chomp.

'abc123'.chomp('123')    # => "abc"

chomp계산 의 이점 은 다음 과 같습니다. 계산 없음. 코드가 수행중인 작업을보다 명확하게 전달합니다.

인수없이 chompDOS 또는 Unix 줄 끝이 있으면 제거합니다.

"abc\n".chomp      # => "abc"
"abc\r\n".chomp    # => "abc"

의견에서 사용 속도 #chomp와 범위 사용에 대한 질문이있었습니다 . 다음은 두 가지를 비교 한 벤치 마크입니다.

require 'benchmark'

S = 'asdfghjkl'
SL = S.length
T = 10_000
A = 1_000.times.map { |n| "#{n}#{S}" }

GC.disable

Benchmark.bmbm do |x|
  x.report('chomp') { T.times { A.each { |s| s.chomp(S) } } }
  x.report('range') { T.times { A.each { |s| s[0...-SL] } } }
end

벤치 마크 결과 (CRuby 2.13p242 사용) :

Rehearsal -----------------------------------------
chomp   1.540000   0.040000   1.580000 (  1.587908)
range   1.810000   0.200000   2.010000 (  2.011846)
-------------------------------- total: 3.590000sec

            user     system      total        real
chomp   1.550000   0.070000   1.620000 (  1.610362)
range   1.970000   0.170000   2.140000 (  2.146682)

따라서 Chomp는 범위를 사용하는 것보다 ~ 22 % 빠릅니다.


5
잘라내기도 옵션입니다. 무엇이 제거되는지에 대해 까다 롭지 않습니다.
Andrew Grimm

1
나는 그 반대가 실제로 사실이라는 것을 알았다. 현실은 .chomp가 지속적으로 두 배 빠른 것 같습니다.
Plasmarob

3
@Plamarob, Ruby의 벤치 마크는 종종 놀랍습니다. 나는 종종 잘못되어 더 이상 무엇이 더 빠를 지 추측하지 않습니다. 또한 벤치 마크 결과로 답변이 개선 될 경우 자유롭게 편집하십시오.
Wayne Conrad

1
코드를 올바르게 읽으면 레인지보다 약 53 나노 초가 걸립니다. 특정 상황에서는 상당한 드래그가 될 수 있지만, 상대 속도가 아닌 절대 속도를 염두에두면 코드베이스를 통과하고 모든 범위를 촘촘하게 바꿀 수 있는지 여부를 알 수 있습니다 (해당되는 경우). 아마 아닙니다.
cesoid 2016 년

1
잘 작동합니다. 그리고 당신은 chomp!()그 자리에서 문자열에 작용할 수 있습니다 .
Joshua Pinter

57
str = str[0...-n]

5
이것은 Ruby 1.9에서만 작동합니다. Ruby 1.8에서는 마지막 문자가 아닌 마지막 바이트 를 제거합니다 .
Jörg W Mittag

5
-n은 문자열의 끝에서 n 개의 문자를 가져 오기 때문에 3 개의 점 (...)이 기억하기 쉬우므로 선택한 답보다 낫습니다.
lulalala

또한 "abcd"[0 ..- 2] # => "abc"동안 "abcd"[0 ...- 2] # => "ab". 제 생각에 3 도트 범위 옵션은 더 자명 한 코드를 만듭니다.
mokagio

31

나는 제안 할 것이다 chop. 나는 그것이 주석 중 하나에서 언급되었지만 링크 나 설명이없는 것으로 생각하므로 여기에 더 나은 이유가 있습니다.

단순히 문자열에서 마지막 문자를 제거하기 때문에 해당 값을 지정하지 않아도됩니다.

하나 이상의 캐릭터를 제거해야한다면 chomp가장 좋은 방법입니다. 이것이 루비 문서 들이 말하는 것입니다 chop:

마지막 문자가 제거 된 새 문자열을 반환합니다. 문자열이 \ r \ n으로 끝나면 두 문자가 모두 제거됩니다. 빈 문자열에 잘라내기를 적용하면 빈 문자열이 반환됩니다. String # chomp는 레코드 구분 기호로 끝나지 않으면 문자열을 변경하지 않고 그대로 두는 것이 더 안전한 대안입니다.

이것은 주로 구분 기호를 제거하는 데 사용되지만 \r\n예를 들어 s단어를 단수로 만드는 것과 같이 간단한 문자열에서 마지막 문자를 제거하는 데 사용했습니다 .


1
마지막 문자 하나만 제거하지 않습니까? 문제는 복수형의 "캐릭터"에 관한 것입니다.
maetthew

1
네, 맞습니다. 그러나 chomp ( 'chars')는 마지막 'chars'를 제거합니다. OP가 특정 문자를 원했는지 아니면 N 문자 만 원했는지는 분명하지 않았습니다.
kakubei

네, 이것은 하나의 캐릭터 만 제거하고 싶을 때만 답입니다.
Quv

29
name = "my text"
x.times do name.chop! end

여기 콘솔에서 :

>name = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do name.chop! end
 => 7 
> name
 => "Nabuco" 

이것이 효율적입니까? 하나는 다른 답변과 비교할만한 벤치 마크 가치가있는 것 같습니다 :)
SRack

16

마지막 n문자를 삭제 하는 것은 첫 length - n문자 를 유지하는 것과 같습니다 .

활성 지원에는 첫 번째 / 마지막 문자 를 유지하거나 삭제하는 편리한 방법을 제공하는 방법 String#firstString#last방법이 포함됩니다 n.

require 'active_support/core_ext/string/access'

"foobarbaz".first(3)  # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3)   # => "baz"
"foobarbaz".last(-3)  # => "barbaz"

7

레일을 사용하는 경우 다음을 시도하십시오.

"my_string".last(2) # => "ng"

[편집 됨]

마지막 두 문자없이 문자열을 얻으려면 :

n = "my_string".size
"my_string"[0..n-3] # => "my_stri"

참고 : 마지막 문자열 문자는 n-1입니다. 따라서 마지막 2를 제거하기 위해 n-3을 사용합니다.


2
마지막 두 글자는 제거되지 않습니다. 그것들을 돌려줍니다.
JP Silvashy

1
문자열을 먼저 측정 할 필요는 없습니다. 루비는 문자열의 끝에서 음의 색인을 사용합니다
Devon Parsons

3

당신은 항상 같은 것을 사용할 수 있습니다

 "string".sub!(/.{X}$/,'')

X제거 할 문자 수는 어디에 있습니까 ?

또는 결과를 할당 / 사용하는 경우 :

myvar = "string"[0..-X]

여기서 X문자 수에 제거 할 문자 수를 더한 것 입니다.



1

클래스 메소드 작성에 문제가없고 잘리는 문자를 원하면 다음을 시도하십시오.

class String
  def chop_multiple(amount)
    amount.times.inject([self, '']){ |(s, r)| [s.chop, r.prepend(s[-1])] }
  end
end

hello, world = "hello world".chop_multiple 5
hello #=> 'hello '
world #=> 'world'

0

정규식 사용 :

str = 'string'
n = 2  #to remove last n characters

str[/\A.{#{str.size-n}}/] #=> "stri"

0

제거하려는 문자가 항상 같은 문자 인 경우 chomp을 고려하십시오.

'abc123'. mp 프 ( '123')


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.