Chỉ viết hoa ký tự đầu tiên của chuỗi và để nguyên những ký tự khác? (Đường ray)


102

Tôi đang cố gắng để Rails viết hoa ký tự đầu tiên của một chuỗi và giữ nguyên tất cả các ký tự khác. Tôi đang gặp phải sự cố trong đó "tôi đến từ New York" bị chuyển thành "Tôi đến từ New York".

Tôi sẽ sử dụng phương pháp nào để chọn ký tự đầu tiên?

Cảm ơn

CHỈNH SỬA: Tôi đã cố gắng triển khai những gì macek đề xuất, nhưng tôi gặp lỗi "phương pháp không xác định` `capitalize '" . Mã hoạt động tốt mà không có dòng viết hoa. Cảm ơn đã giúp đỡ!

def fixlistname!
  self.title = self.title.lstrip + (title.ends_with?("...") ? "" : "...")
  self.title[0] = self.title[0].capitalize
  errors.add_to_base("Title must start with \"You know you...\"") unless self.title.starts_with? 'You know you'
end

CHỈNH SỬA 2: Đã hoạt động. Cảm ơn đã giúp đỡ!

CHỈNH SỬA 3: Chờ đã, không, tôi không ... Đây là những gì tôi có trong mô hình danh sách của mình.

def fixlistname!
  self.title = self.title.lstrip + (title.ends_with?("...") ? "" : "...")
  self.title.slice(0,1).capitalize + self.title.slice(1..-1)
  errors.add_to_base("Title must start with \"You know you...\"") unless self.title.starts_with?  'You know you'
end

CHỈNH SỬA 4: Đã thử chỉnh sửa của macek và vẫn nhận được lỗi phương thức không xác định `` capitalize '" . Tôi có thể làm gì sai?

def fixlistname!
  self.title = title.lstrip
  self.title += '...' unless title.ends_with?('...')
  self.title[0] = title[0].capitalize
  errors.add_to_base('Title must start with "You know you..."') unless title.starts_with?("You know you")
end

CHỈNH SỬA 5: Điều này thật kỳ lạ. Tôi có thể loại bỏ lỗi phương thức không xác định bằng cách sử dụng dòng bên dưới. Vấn đề là nó dường như thay thế chữ cái đầu tiên bằng một con số. Ví dụ: thay vì viết hoa chữ y trong You , nó biến chữ y thành 121

self.title[0] = title[0].to_s.capitalize

Dựa trên EDIT 3, bạn cần bắt đầu dòng 2 với self.title = . Ngoài ra, trên cả 3 dòng, bạn chỉ cần self.titlebên trái một =(dấu bằng). Ở những nơi khác, bạn chỉ có thể sử dụng title. Xem phần chỉnh sửa câu trả lời của tôi để làm ví dụ.
Macek

2
Vấn đề trong Edit4 là bạn chỉ có một ký tự - không còn là một chuỗi - do đó nó sẽ không nhận ra chuỗi-hàm "viết hoa".
Taryn East

Vấn đề với Chỉnh sửa 5 là tiêu đề [0] là một định dạng, vì vậy việc gọi tiêu đề [0] .to_s sẽ chỉ cung cấp cho bạn số ký tự (tức là 121 dưới dạng chuỗi: "121"). Bạn có thể làm self.title [0] = title.first.capitalize nếu bạn muốn!
Nick

Tôi đã thêm #upcase_first_case và thực hiện một yêu cầu kéo: github.com/rails/rails/pull/15319 . Vui lòng thêm phản hồi của bạn ở đó.
Aldo 'xoen' Giambelluca

Câu trả lời:


93

Titleize sẽ viết hoa mọi từ. Dòng này có vẻ nặng nề, nhưng sẽ đảm bảo rằng chữ cái duy nhất được thay đổi là chữ cái đầu tiên.

new_string = string.slice(0,1).capitalize + string.slice(1..-1)

Cập nhật:

irb(main):001:0> string = "i'm from New York..."
=> "i'm from New York..."
irb(main):002:0> new_string = string.slice(0,1).capitalize + string.slice(1..-1)
=> "I'm from New York..."

Chờ mãi vẫn không được. Cảnh báo sai: / Tôi nghĩ rằng tôi chỉ đang triển khai sai.
Daniel O'Connor

1
Daniel - nói chung là hình thức tốt để "chấp nhận" một câu trả lời giải quyết được vấn đề của bạn. Bạn có thể làm điều này bằng cách nhấp vào "đánh dấu" ở bên trái của câu trả lời. :)
Taryn East,

1
Tôi đã hiểu sai câu hỏi, nếu không tôi muốn cho bạn 1 up. Tôi đã tìm kiếm .titleize thay vì .capitalize. Cảm ơn bạn anyway Taryn!
Eric Wanchic

OOC - Tại sao điều đó lại ngăn cản bạn từ bỏ sự ủng hộ? Tôi đã trả lời chính xác câu hỏi của người đăng ban đầu chưa? Nếu bạn nghĩ như vậy - thì hãy ủng hộ. Nó không phải phụ thuộc vào bất cứ điều gì khác ... :)
Taryn Đông

2
Vì vậy, đây là thông tin: s[0].capitalize + s[1..-1] if s.present?
Alex Escalante

126

Điều này nên làm điều đó:

title = "test test"     
title[0] = title[0].capitalize
puts title # "Test test"

40
Hoặc ngắn gọn hơn,title[0] = title[0].capitalize
Jon Garvin

Đây là một giải pháp rất thanh lịch.
Karew

1
@JonGarvin title [0] .capitalize không hoạt động (ít nhất là với Ruby 1.8.7), vì title [0] trả về Fixnum và viết hoa mong đợi một chuỗi .. vì vậy tôi nghĩ title.first.capitalize là cách để đi.
Nick

2
xấu hổ bạn không thểtitle.first.capitalize!
Adam Waite

1
capitalizechuyển đổi tất cả các chữ cái sau chữ cái đầu tiên thành chữ thường, vì vậy nó không hoạt động đối với chuỗi được trình bày trong câu hỏi ("tôi đến từ New York").
Mark Schneider

57

Bạn có thể sử dụng nhân hóa. Nếu bạn không cần dấu gạch dưới hoặc viết hoa khác trong các dòng văn bản của mình.

Đầu vào:

"i'm from New_York...".humanize

Đầu ra:

"I'm from new york..."

7
OP đặc biệt muốn tránh 'new york'
phatmann 5/12/12

Quả thực là hơi quá nhanh với câu trả lời của tôi.
Bartuzz

17
@Bartuzz Mặc dù đây không phải là những gì OP muốn, nhưng đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn!
Yetti

new york tuy nhiên sẽ không có ngữ âm như một danh từ riêng và nên sử dụng chữ hoa.
Shayne

Được cảnh báo, humanizelà phương thức Rails, chính xác là ActiveSupport. Ruby trơn không thể làm được điều đó.
Penguin

51
str = "this is a Test"
str.sub(/^./, &:upcase)
# => "This is a Test"

1
Cô đọng và trang nhã. Tôi tin rằng đây phải là câu trả lời hàng đầu.
Chris

Tôi đồng ý. Tôi nghĩ đây phải là câu trả lời được chấp nhận.
Garry Pettet.

Một điều kỳ quặc là kể từ ^đầu dòng, "\nfoo"trở thành "\nFoo". Điều đó có lẽ tốt cho hầu hết các trường hợp sử dụng. Vì nó là a subchứ không phải a gsub, nó sẽ vẫn chỉ viết hoa một chữ cái, ngay cả với các chuỗi nhiều dòng.
Henrik N

Có thể nhận được giới hạn ở trên bằng cách sử dụng str.sub(/\S/, &:upcase), sẽ tìm ký tự không có khoảng trắng đầu tiên và viết hoa nó.
Anthony Panozzo

39

Đối với Rails 5.0.0.beta4, bạn có thể sử dụng String#upcase_firstphương pháp mới hoặc ActiveSupport::Inflector#upcase_firstthực hiện điều đó. Kiểm tra bài đăng trên blog này để biết thêm thông tin.


Đó là tin tuyệt vời! Tôi đang nghĩ chúng ta có thể làm gì ngay bây giờ và có lẽ một polyfill cho Rails 4 sẽ rất hay.
hakunin

Lưu ý rằng upcase_first và không xử lý dấu / ký tự đặc biệt, ngay cả với mb_chars
user3033467

14

Một giải pháp hướng đối tượng:

class String
  def capitalize_first_char
    self.sub(/^(.)/) { $1.capitalize }
  end
end

Sau đó, bạn chỉ có thể làm điều này:

"i'm from New York".capitalize_first_char

Ít nhất ai đó đã viết giải pháp thanh lịch với việc mở rộng Stringlớp học.
Dmitriy

@Dmitriy tại sao con khỉ vá dây lại thanh lịch?
Gerard Simpson


6

Chỉnh sửa 2

Tôi dường như không thể lặp lại rắc rối của bạn. Hãy tiếp tục và chạy tập lệnh Ruby gốc này. Nó tạo ra kết quả chính xác mà bạn đang tìm kiếm và Rails hỗ trợ tất cả các phương pháp này. Bạn đang gặp khó khăn với loại đầu vào nào?

#!/usr/bin/ruby
def fixlistname(title)
  title = title.lstrip
  title += '...' unless title =~ /\.{3}$/
  title[0] = title[0].capitalize
  raise 'Title must start with "You know you..."' unless title =~ /^You know you/
  title
end

DATA.each do |title|
  puts fixlistname(title)
end

__END__
you know you something WITH dots ...
you know you something WITHOUT the dots
  you know you something with LEADING whitespace...
  you know you something with whitespace BUT NO DOTS
this generates error because it doesn't start with you know you

đầu ra

You know you something WITH dots ...
You know you something WITHOUT the dots...
You know you something with LEADING whitespace...
You know you something with whitespace BUT NO DOTS...
RuntimeError: Title must start with "You know you..."

Biên tập

Dựa trên chỉnh sửa của bạn, bạn có thể thử một cái gì đó như thế này.

def fixlistname!
  self.title = title.lstrip
  self.title += '...' unless title.ends_with?('...')
  self.title[0] = title[0].capitalize
  errors.add_to_base('Title must start with "You know you..."') unless title.starts_with?("You know you")
end

Nguyên

Điều này sẽ thực hiện thủ thuật

s = "i'm from New York"
s[0] = s[0].capitalize
#=> I'm from New York

Khi cố gắng sử dụng String#capitalizetrên toàn bộ chuỗi, bạn đã thấy I'm from new yorkvì phương thức:

Trả về một bản sao của str với ký tự đầu tiên được chuyển đổi thành chữ hoa và phần còn lại thành chữ thường.

"hello".capitalize    #=> "Hello"
"HELLO".capitalize    #=> "Hello"
"123ABC".capitalize   #=> "123abc"

1 nguyên nhân tôi không nghĩ rằng sẽ làm việc cho đến khi tôi đã thử nó trên pc của tôi :)
Jeriko

Xin chào, cảm ơn vì sự giúp đỡ. Tôi đang làm gì sai? Tôi đã chỉnh sửa câu hỏi ban đầu để bao gồm mã của mình.
Daniel O'Connor

Tôi đã sử dụng gợi ý của Taryn và nó hoạt động. Cảm ơn sự giúp đỡ của bạn!
Daniel O'Connor

Xin chào, stackoverflow cho biết bạn đã chỉnh sửa, nhưng tôi không thấy điều gì khác biệt?
Daniel O'Connor

6
my_string = "hello, World"
my_string.sub(/\S/, &:upcase) # => "Hello, World"

Không thất bại nếu my_string trống! Đẹp. Đây là những gì tôi cần.
Huliax

4

Hầu hết các câu trả lời này đều chỉnh sửa chuỗi tại chỗ, khi bạn chỉ định dạng cho đầu ra dạng xem, bạn có thể không muốn thay đổi chuỗi bên dưới để bạn có thể sử dụng tapsau a dupđể nhận bản sao đã chỉnh sửa

'test'.dup.tap { |string| string[0] = string[0].upcase }

3

Nếu và chỉ nếu OP muốn thực hiện thao tác vá khỉ trên đối tượng Chuỗi, thì điều này có thể được sử dụng

class String
  # Only capitalize first letter of a string
  def capitalize_first
    self.sub(/\S/, &:upcase)
  end
end

Bây giờ sử dụng nó:

"i live in New York".capitalize_first #=> I live in New York

2

Một phiên bản ngắn hơn nữa có thể là:

s = "i'm from New York..."
s[0] = s.capitalize[0]

2

Không ai đề cập đến gsub, cho phép bạn làm điều này một cách ngắn gọn.

string.gsub(/^([a-z])/) { $1.capitalize }

Thí dụ:

 > 'caps lock must go'.gsub(/^(.)/) { $1.capitalize }
=> "Caps lock must go"

1

Có lẽ là cách dễ nhất.

s = "test string"
s[0] = s[0].upcase
# => "Test string"

1

Lưu ý rằng nếu bạn cần xử lý các ký tự nhiều byte, tức là nếu bạn phải quốc tế hóa trang web của mình, thì s[0] = ...giải pháp sẽ không phù hợp. Câu hỏi Stack Overflow này đề xuất sử dụng viên ngọc unicode- using

Ruby 1.9: Làm cách nào để tôi có thể viết hoa và viết thường các chuỗi multibyte đúng cách?

BIÊN TẬP

Trên thực tế, một cách dễ dàng hơn để ít nhất là tránh các mã hóa chuỗi lạ là chỉ sử dụng Chuỗi # mb_chars :

s = s.mb_chars
s[0] = s.first.upcase
s.to_s

0

Còn về phương thức phân loại trên chuỗi thì sao?

'somESTRIng'.classify

đầu ra:

#rails => 'SomESTRIng'

1
Nó đang làm rất nhiều thứ bổ sung, chẳng hạn như các từ đơn lẻ hóa. "hello worlds".classify # => "Hello world"
Pavel Pravosud

-3
string = "i'm from New York"
string.split(/\s+/).each{ |word,i| word.capitalize! unless i > 0 }.join(' ')
# => I'm from New York

Có vẻ như vậy. Tôi mới làm quen với ruby ​​và các câu trả lời khác không thực sự làm theo những gì OP yêu cầu, vì vậy tôi đã làm cho nó hoạt động: D Hãy sửa cho tôi nếu tôi sai, nhưng AFAIK sửa đổi một chuỗi bằng cách thay đổi chuỗi [i] thì không làm việc trong nhiều ngôn ngữ?
Jeriko

3
đây là một câu hỏi dành riêng cho Ruby. Nó không quan trọng nếu string[i]không hoạt động trong các ngôn ngữ khác. Vui lòng giúp StackOverflow không có những câu trả lời bị tấn công kiểu này. Chúng tôi không thể nói RTFM, nhưng ngay cả một cái nhìn nhanh về Stringtài liệu cũng sẽ giúp tránh được câu trả lời như thế này ...
maček
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.