Xóa chuỗi con khỏi chuỗi


193

Tôi chỉ tự hỏi nếu có bất kỳ phương pháp để loại bỏ chuỗi từ một chuỗi khác? Một cái gì đó như thế này:

class String
  def remove(s)
    self[s.length, self.length - s.length]
  end
end

Câu trả lời:


263

Bạn có thể sử dụng phương pháp lát:

a = "foobar"
a.slice! "foo"
=> "foo"
a
=> "bar"

không có '!' phiên bản là tốt. Cũng có thể xem thêm thông tin trong tài liệu về các phiên bản khác: http://www.ruby-doc.org/core/groupes/String.html#method-i-slice-21


1
Rất thanh lịch! Bạn cũng có thể sử dụng []s cho phiên bản không bang.
Matheus Moreira

65
Điều này có tác dụng phụ xấu là trả lại văn bản đã xóa (hoặc văn bản tìm kiếm). Không may cho chuỗi kết quả của việc xóa.
Mike

10
Làm thế nào để bạn trả lại chuỗi cắt và không ảnh hưởng đến bản gốc? Ví dụ: nếu tôi có "hello world", tôi muốn cắt "hello" và chỉ trả lại phần "world", mà không sửa đổi đối tượng chuỗi gốc?
jhabbott

14
@Mike"foobar".tap{|s| s.slice!("foo")}.upcase
Ernest

7
@bcackerman - deletesẽ không hoạt động, vì nó sẽ xóa tất cả các ký tự bạn chuyển qua:'hello world'.delete('hello') #=> ' wrd'
rỉ sét

165

Làm thế nào về str.gsub("subString", "") Kiểm tra Ruby Doc


38
subsẽ phù hợp hơn gsub, vì OP chỉ muốn loại bỏ chuỗi con khỏi đầu chuỗi chứ không phải tất cả thông qua chuỗi (nhìn vào mã mẫu của anh ấy). Và sử dụng regex, như thế này, sẽ tốt hơn: str.sub(/^subString/, '')- bởi vì nó đảm bảo rằng chuỗi con chắc chắn sẽ bị xóa chỉ từ đầu.
Alex D

@AlexD Sử dụng regex sẽ tốt hơn, nhưng sẽ nguy hiểm nếu chúng ta không chắc chắn subStringkhông bao gồm bất kỳ ký tự đặc biệt nào của regex.
David Moles

@DavidMoles, trong trường hợp /^subString/này là một nghĩa đen, vì vậy chúng tôi có thể rất chắc chắn rằng nó không bao gồm bất kỳ siêu nhân vật nào. Nếu bạn đang thay thế một số chuỗi khác thành regex, bạn có thể làm điều này : /#{Regexp.escape(str)}/.
Alex D

Trong câu trả lời, có, nhưng không phải trong câu hỏi của OP. Cảm ơn con trỏ đến Regexp.escape(), mặc dù.
David Moles

105

Nếu nó là phần cuối của chuỗi, bạn cũng có thể sử dụng chomp:

"hello".chomp("llo")     #=> "he"

nếu biểu thức là a.chomp ("llo"), chomp! chính xác hơn
Fernando Gonzalez Sanchez

1
Cái này sạch hơn lát!, Vì nó không có tác dụng phụ.
Ardee Aram

5
Nếu đó là từ đầu chuỗi, bạn cũng có thể sử dụng chompkết hợp với reverse:"hello".reverse.chomp("he".reverse).reverse #=> "llo"
amoebe

45

Nếu bạn chỉ có một lần xuất hiện của chuỗi mục tiêu, bạn có thể sử dụng:

str[target] = ''

hoặc là

str.sub(target, '')

Nếu bạn có nhiều lần sử dụng mục tiêu:

str.gsub(target, '')

Ví dụ:

asdf = 'foo bar'
asdf['bar'] = ''
asdf #=> "foo "

asdf = 'foo bar'
asdf.sub('bar', '') #=> "foo "
asdf = asdf + asdf #=> "foo barfoo bar"
asdf.gsub('bar', '') #=> "foo foo "

Nếu bạn cần thay thế tại chỗ, hãy sử dụng các "!"phiên bản gsub!sub!.


2
ruby là niềm vui thực sự thích nhìn thấy những thứ như:asdf['bar'] = ''
Peter Butkovic

1
Tôi sẽ không gọi đó là "niềm vui" - có lẽ không trực quan.
Jmoney38

31

Nếu bạn đang sử dụng Rails cũng có remove.

Ví dụ "Testmessage".remove("message")sản lượng "Test".

Cảnh báo: phương pháp này loại bỏ tất cả các lần xuất hiện


1
Đây không phải là câu trả lời của vanilla Ruby, nhưng câu trả lời được chấp nhận không hoàn toàn là điều mà hầu hết mọi người đang tìm kiếm. Thật không may, slicephương thức này không trả về phần của chuỗi bị cắt, nó trả về "con dao"
Dylan Pierce

1
@DylanPierce Thật dễ dàng để thực hiện một chức năng sử dụngslice! def gimme_the_slice(my_string, my_slice) my_string.slice!(my_slice) my_string
Bennett Talpers

1
À đúng rồi, bang-ifying là cách Ruby sửa đổi biến hiện có. Cảm ơn @BennettTalpers
Dylan Pierce

26

Ruby 2.5+

Nếu chuỗi con của bạn ở đầu chuỗi cuối, thì Ruby 2.5 đã giới thiệu các phương thức cho việc này:

  • xóa_prefix để xóa một chuỗi con từ đầu chuỗi
  • xóa_suffix để xóa một chuỗi con khỏi cuối chuỗi


1

Nếu tôi giải thích đúng, câu hỏi này dường như yêu cầu một cái gì đó giống như một phép toán trừ (-) giữa các chuỗi, tức là ngược lại với phép toán cộng (+) tích hợp (nối).

Không giống như các câu trả lời trước, tôi đang cố gắng xác định một hoạt động như vậy phải tuân theo thuộc tính:

NẾU c = a + b THEN c - a = b VÀ c - b = a

Chúng tôi chỉ cần ba phương thức Ruby tích hợp để đạt được điều này:

'abracadabra'.partition('abra').values_at(0,2).join == 'cadabra'.

Tôi sẽ không giải thích cách nó hoạt động bởi vì có thể dễ dàng hiểu được khi chạy một phương thức tại một thời điểm.

Dưới đây là một bằng chứng về mã khái niệm:

# minus_string.rb
class String
  def -(str)
    partition(str).values_at(0,2).join
  end
end

# Add the following code and issue 'ruby minus_string.rb' in the console to test
require 'minitest/autorun'

class MinusString_Test < MiniTest::Test

  A,B,C='abra','cadabra','abracadabra'

  def test_C_eq_A_plus_B
    assert C == A + B
  end

  def test_C_minus_A_eq_B
    assert C - A == B
  end

  def test_C_minus_B_eq_A
    assert C - B == A
  end

end

Một lời khuyên cuối cùng nếu bạn đang sử dụng phiên bản Ruby gần đây (> = 2.0): sử dụng các sàng lọc thay vì Chuỗi vá khỉ như trong ví dụ trước.

Nó dễ dàng như:

module MinusString
  refine String do
    def -(str)
      partition(str).values_at(0,2).join
    end
  end
end

và thêm using MinusStringtrước các khối nơi bạn cần nó.


+1 cho các khái niệm về tinh chỉnh. Mặc dù lớp String vá khỉ có lẽ là quá mức cần thiết cho trường hợp sử dụng này, đôi khi chúng ta phải vá các thứ và khái niệm tinh chỉnh thực sự tỏa sáng ở nó.
wonderersz1

-2

đây là những gì tôi sẽ làm

2.2.1 :015 > class String; def remove!(start_index, end_index) (end_index - start_index + 1).times{ self.slice! start_index }; self end; end;
2.2.1 :016 >   "idliketodeleteHEREallthewaytoHEREplease".remove! 14, 32
 => "idliketodeleteplease" 
2.2.1 :017 > ":)".remove! 1,1
 => ":" 
2.2.1 :018 > "ohnoe!".remove! 2,4
 => "oh!" 

Được định dạng trên nhiều dòng:

class String
    def remove!(start_index, end_index)
        (end_index - start_index + 1).times{ self.slice! start_index }
        self
    end 
end

-7
def replaceslug
  slug = "" + name
    @replacements = [
      [ "," , ""],
      [ "\\?" , ""],
      [ " " , "-"],
      [ "'" , "-"],
      [ "Ç" , "c"],
      [ "Ş" , "s"],
      [ "İ" , "i"],
      [ "I" , "i"],
      [ "Ü" , "u"],
      [ "Ö" , "o"],
      [ "Ğ" , "g"],
      [ "ç" , "c"],
      [ "ş" , "s"],
      [ "ı" , "i"],
      [ "ü" , "u"],
      [ "ö" , "o"],
      [ "ğ" , "g"],
    ]
  @replacements.each do |pair|
    slug.gsub!(pair[0], pair[1])
  end
  self.slug = slug.downcase
end

1
Tại sao nhiều phiếu giảm? bạn đã làm gì sai .. có thể quá rộng
zee

OP không yêu cầu xóa Öví dụ.
Iulian Onofrei
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.