2012-02-02 36 views
14

Tôi muốn 'Đây là Thử nghiệm 101' là 'Đây là Thử nghiệm', nhưng tôi không thể có được cú pháp đúng.Làm cách nào để xóa ký tự không phải từ khỏi văn bản?

src = 'This Is A 101 Test' 
puts "A) " + src      # base => "This Is A 101 Test" 
puts "B) " + src[/([a-z]+)/]   # only does first word => "his" 
puts "C) " + src.gsub!(/\D/, "")  # Does digits, I want alphabetic => "101" 
puts "D) " + src.gsub!(/\W///g)  # Nothing. => "" 
puts "E) " + src.gsub(/(\W|\d)/, "") # Nothing. => "" 

Trả lời

27

Trước hết, bạn cần phải cẩn thận với gsubgsub!. Cái sau là "nguy hiểm!" và sẽ sửa đổi giá trị của src. Nếu bạn đang thực hiện các câu lệnh này theo thứ tự, hãy lưu ý rằng a.gsub!(/a/, "b")a = a.gsub(/a/, "b") cả hai sẽ làm điều tương tự với a. Một phần của vấn đề với mã của bạn là src đang được sửa đổi.

Phương pháp B trả "his" nhưng không có sự thay đổi để source

src[/([a-z]+)/]  # => "his" 
src     # => "This Is A 101 Test" 

Phương pháp C loại bỏ tất cả các ký tự mà không số:

src.gsub!(/\D/, "") # => "101" 
src     # => "101" 

Phương pháp D không hoạt động bởi vì cú pháp là sai. Phương thức gsub chấp nhận một biểu thức/chuỗi thông thường để tìm kiếm và sau đó một chuỗi để sử dụng để thay thế. Nếu bạn thử nó trong IRB, nó sẽ hoạt động như thể bạn cần một số khác /.

E phương pháp thay thế tất cả các ký tự không lời nói và tất cả các số:

src.gsub(/(\W|\d)/, "") # => "This Is A Test" (note the two spaces) 
src      # => "This Is A 101 Test" 

Bạn chỉ ra rằng nó trở "". Vâng, những gì thực sự xảy ra là C và D như được liệt kê (với các vấn đề cú pháp cố định) là phá hoại thay đổi. (Ngoài ra, nếu chạy trên "101", D sẽ thực sự trở lại nil như không có sự thay thế đã được thực hiện.) Vì vậy, E được chỉ được chạy trên "101", và kể từ khi bạn đang thay thế tất cả các phi từ tất cả các số với "", nó trở nên "101" .


Câu trả lời bạn đang tìm kiếm sẽ là một cái gì đó như:

src.gsub!(/\d\s?/, "") # => "This Is A Test" 
src     # => "This Is A Test" 

Và yêu thích của tôi để đối phó với tất cả các kịch bản của không gian hai (vì squeeze là khá hiệu quả trong việc kết hợp như nhân vật, strip là khá hiệu quả trong việc tước khoảng trắng ở cuối và những người đó ! trả lại nil nếu họ không thực hiện thay thế):

src = src.gsub(/\d+/, "").squeeze(" ").strip 
+0

vị trí bật. cảm ơn! –

4

Bạn có muốn cắt '101' khỏi chuỗi không? Dưới đây là regex của bạn

src = 'This Is A 101 Test' 

puts src.gsub /\ \d+/, '' 
# => This Is A Test 

Ngoài ra tôi không hiểu tại sao bạn đang sử dụng phiên bản bang gsub. gsub! sửa đổi chuỗi gốc, gsub sao chép và sửa đổi bản sao.

+0

Không làm việc: 'đặt "F)" + src.gsub/\ d + /, '' ^' –

+2

@MichaelDurrant: nó hoạt động. Chuỗi của bạn không phải là những gì bạn nghĩ là nó nữa. Thay đổi 'gsub!' Thành 'gsub' và thử lại. –

+0

Làm việc cho tôi. Làm điều đó chính xác như ông đã đăng. 'đặt src.gsub (/ \ \ d + /, '')'. Như @SergioTulentsev đã nói, bạn không nên sử dụng phiên bản 'bang' của phương thức' gsub'. [Đọc tài liệu cho phiên bản bang] (http://ruby-doc.org/core-1.9.3/String.html#method-i-gsub-21), nó thao tác chuỗi gốc. – Batkins

3

Bạn có muốn xóa số không? Nếu vậy, src.gsub(/\d/,"") sẽ hoạt động. Lý do nó không hoạt động ở trên là gsub! sửa đổi chuỗi nó được gọi là, vì vậy sau C, src = "101" và loại bỏ tất cả các chữ số để lại một chuỗi rỗng.

Nếu bạn muốn loại bỏ mọi thứ trừ ký tự chữ cái và dấu cách (tức là chữ số và dấu chấm câu), src.gsub(/(?=\S)(\d|\W)/,"") sẽ hoạt động.

Nếu bạn muốn loại bỏ mọi thứ trừ ký tự chữ cái (loại bỏ dấu cách cũng như chữ số và dấu chấm câu), src.gsub(/\d|\W/,"") sẽ hoạt động.

8

Để xóa tất cả "các ký tự không phải từ", bạn chỉ có thể giữ những ký tự đó.

src = 'This Is A 101 Test' 
src.gsub(/[^a-zA-Z ]/,'').gsub(/ +/,' ') 
=> "This Is A Test" 

Tôi khuyên bạn nên Rubular để thử biểu thức chính quy Ruby.

+1

+1 cho rubular, thật tuyệt vời! –

7

Không regexp:

src = 'This Is A 101 Test' 
src.delete('^a-zA-Z ') #the^negates everything 
Các vấn đề liên quan