Nur das erste Zeichen der Zeichenfolge groß schreiben und andere in Ruhe lassen? (Schienen)


102

Ich versuche, Rails dazu zu bringen, das erste Zeichen einer Zeichenfolge groß zu schreiben und alle anderen so zu belassen, wie sie sind. Ich habe ein Problem, bei dem aus "Ich komme aus New York" "Ich komme aus New York" wird.

Mit welcher Methode würde ich das erste Zeichen auswählen?

Vielen Dank

BEARBEITEN: Ich habe versucht zu implementieren, was macek vorgeschlagen hat, aber ich erhalte den Fehler "undefinierte Methode" großschreiben "" . Der Code funktioniert ohne Groß- und Kleinschreibung. Danke für die Hilfe!

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

EDIT 2: Hat es funktioniert. Danke für die Hilfe!

EDIT 3: Warten Sie, nein, ich habe nicht ... Hier ist, was ich in meinem Listenmodell habe.

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

EDIT 4: Versucht, Macek zu bearbeiten und trotzdem einen undefinierten Methodenfehler zu erhalten . Was könnte ich falsch machen?

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

EDIT 5: Das ist komisch. Ich kann den undefinierten Methodenfehler mithilfe der folgenden Zeile beseitigen. Das Problem ist, dass es scheint, den ersten Buchstaben durch eine Zahl zu ersetzen. Anstatt beispielsweise das y in You groß zu schreiben , verwandelt es das y in ein 121

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

Basierend auf EDIT 3müssen Sie Zeile 2 mit beginnen self.title = . Außerdem benötigen Sie in allen drei Zeilen nur self.titlelinks von einem =(Gleichheitszeichen). An anderen Stellen können Sie einfach verwenden title. Ein Beispiel finden Sie in der Bearbeitung meiner Antwort.
Maček

2
Das Problem in Edit4 ist, dass Sie nur ein Zeichen haben - keine Zeichenfolge mehr - und daher die Zeichenfolgenfunktion "großschreiben" nicht erkennen.
Taryn East

Das Problem bei Edit 5 ist, dass title [0] eine Fixnummer ist. Wenn Sie also title [0] .to_s aufrufen, erhalten Sie nur die Zeichennummer (dh 121 als Zeichenfolge: "121"). Sie können self.title [0] = title.first.capitalize ausführen, wenn Sie möchten!
Nick

Ich habe ein #upcase_first_case hinzugefügt und eine Pull-Anfrage gestellt: github.com/rails/rails/pull/15319 . Fühlen Sie sich frei, Ihr Feedback dort hinzuzufügen.
Aldo 'xoen' Giambelluca

Antworten:


93

Titleize wird jedes Wort groß schreiben. Diese Zeile fühlt sich kräftig an, garantiert aber, dass der einzige geänderte Buchstabe der erste ist.

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

Aktualisieren:

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..."

Warten Sie, funktioniert immer noch nicht. Fehlalarm: / Ich denke, ich implementiere es nur falsch.
Daniel O'Connor

1
Daniel - es ist im Allgemeinen eine gute Form, eine Antwort zu "akzeptieren", die Ihr Problem gelöst hat. Sie können dies tun, indem Sie auf das "Häkchen" links neben der Antwort klicken. :)
Taryn East

1
Ich habe die Frage falsch verstanden, sonst wollte ich dir eine 1 geben. Ich suchte nach .titleize statt .capitalize. Trotzdem danke Taryn!
Eric Wanchic

OOC - Warum hindert Sie das daran, eine Gegenstimme abzugeben? Habe ich die Frage des Originalplakats richtig beantwortet? Wenn du so denkst - dann stimme zu. Es muss nicht von irgendetwas anderem abhängig sein ... :)
Taryn East

2
Also, hier geht es: s[0].capitalize + s[1..-1] if s.present?
Alex Escalante

126

Dies sollte es tun:

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

40
Oder prägnanter,title[0] = title[0].capitalize
Jon Garvin

Dies ist eine sehr elegante Lösung.
Karew

1
@ JonGarvin title [0] .capitalize funktioniert nicht (zumindest mit Ruby 1.8.7), da title [0] ein Fixnum zurückgibt und großschrift eine Zeichenfolge erwartet. Ich denke also, title.first.capitalize ist der Weg dazu gehen.
Nick

2
Schade, dass du nicht kannsttitle.first.capitalize!
Adam Waite

1
capitalizekonvertiert alle Buchstaben nach dem ersten Buchstaben in Kleinbuchstaben, sodass dies für die in der Frage dargestellte Zeichenfolge ("Ich komme aus New York") nicht funktioniert.
Mark Schneider

57

Sie können humanisieren verwenden. Wenn Sie keine Unterstriche oder andere Großbuchstaben in Ihren Textzeilen benötigen.

Eingang:

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

Ausgabe:

"I'm from new york..."

7
Das OP wollte ausdrücklich "New York" vermeiden
Phatmann

Hmm, ein bisschen zu schnell mit meiner Antwort.
Bartuzz

17
@ Bartuzz Auch wenn dies nicht das ist, was OP wollte, ist dies genau das, wonach ich gesucht habe. Vielen Dank!
Yetti

New York wäre jedoch ungrammatisch, da es ein Eigenname ist und Großbuchstaben verwenden sollte.
Shayne

Seien Sie gewarnt, humanizeist die Rails genau ActiveSupport-Methode. Einfacher Rubin kann das nicht.
Pinguin

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

1
Prägnant und elegant. Ich glaube, das sollte die beste Antwort sein.
Chris

Genau. Ich denke, das sollte die akzeptierte Antwort sein.
Garry Pettet

Eine Besonderheit ist, dass da ^bedeutet Zeilenanfang "\nfoo"wird "\nFoo". Das ist wahrscheinlich für die meisten Anwendungsfälle in Ordnung. Da es ein subund kein ist gsub, wird auch bei mehrzeiligen Zeichenfolgen nur ein Buchstabe in Großbuchstaben geschrieben.
Henrik N

Sie können die oben genannte Einschränkung durch Verwendung von erhalten str.sub(/\S/, &:upcase), wodurch das erste Nicht-Leerzeichen gefunden und in Großbuchstaben geschrieben wird.
Anthony Panozzo

39

Ab Rails 5.0.0.beta4 können Sie die neue String#upcase_firstMethode verwenden oder dies ActiveSupport::Inflector#upcase_firsttun. Überprüfen Sie diesen Blog-Beitrag für weitere Informationen.


Das sind gute Nachrichten! Ich dachte, was wir jetzt tun können und vielleicht wäre eine Polyfüllung für Rails 4 schön.
Hakunin

Beachten Sie, dass upcase_first und keine Akzente / Sonderzeichen verarbeitet, auch nicht mit mb_chars
user3033467

14

Eine objektorientierte Lösung:

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

Dann können Sie einfach Folgendes tun:

"i'm from New York".capitalize_first_char

Zumindest hat jemand eine elegante Lösung mit StringKlassenerweiterung geschrieben.
Dmitriy

@Dmitriy warum ist Monkey Patching der String-Klasse elegant?
Gerard Simpson


6

Bearbeiten 2

Ich kann Ihre Probleme nicht wiederholen. Führen Sie dieses native Ruby-Skript aus. Es generiert genau die Ausgabe, nach der Sie suchen, und Rails unterstützt alle diese Methoden. Mit welchen Eingängen haben Sie Probleme?

#!/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

Ausgabe

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..."

Bearbeiten

Basierend auf Ihrer Bearbeitung können Sie so etwas ausprobieren.

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

Original

Dies wird den Trick machen

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

Beim Versuch, String#capitalizedie gesamte Zeichenfolge zu verwenden, wurde Folgendes I'm from new yorkangezeigt:

Gibt eine Kopie von str zurück, wobei das erste Zeichen in Großbuchstaben und der Rest in Kleinbuchstaben konvertiert wird.

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

+1 weil ich nicht dachte, dass das funktionieren würde, bis ich es auf meinem PC ausprobiert habe :)
Jeriko

Hallo, danke für die Hilfe. Was mache ich aber falsch? Ich habe die ursprüngliche Frage so bearbeitet, dass sie meinen Code enthält.
Daniel O'Connor

Ich habe Taryns Vorschlag benutzt und ihn zum Laufen gebracht. Vielen Dank für die Hilfe!
Daniel O'Connor

Hallo, Stackoverflow sagt, Sie haben eine Bearbeitung vorgenommen, aber ich sehe nichts anderes?
Daniel O'Connor

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

Scheitert nicht, wenn my_string leer ist! Nett. Das ist das, was ich benötige.
Huliax

4

Bei den meisten dieser Antworten wird die Zeichenfolge an Ort und Stelle bearbeitet. Wenn Sie nur für die Ansichtsausgabe formatieren, möchten Sie möglicherweise die zugrunde liegende Zeichenfolge nicht ändern, damit Sie tapnach a dupeine bearbeitete Kopie erhalten können

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

3

Wenn und nur wenn OP Affen-Patches für String-Objekte durchführen möchte, kann dies verwendet werden

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

Verwenden Sie es jetzt:

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

2

Eine noch kürzere Version könnte sein:

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

2

Niemand hat gsub erwähnt, wodurch Sie dies präzise tun können.

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

Beispiel:

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

1

Vielleicht der einfachste Weg.

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

1

Beachten Sie, dass die s[0] = ...Lösung nicht ausreicht , wenn Sie sich mit Multi-Byte-Zeichen befassen müssen, dh wenn Sie Ihre Site internationalisieren müssen. Diese Frage zum Stapelüberlauf schlägt vor, das Unicode-Util-Juwel zu verwenden

Ruby 1.9: Wie kann ich Multibyte-Strings richtig auf- und abstellen?

BEARBEITEN

Ein einfacher Weg, um zumindest seltsame String-Codierungen zu vermeiden, ist die Verwendung von String # mb_chars :

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

0

Was ist mit der Klassifizierungsmethode für Zeichenfolgen?

'somESTRIng'.classify

Ausgabe:

#rails => 'SomESTRIng'

1
Es macht eine Menge zusätzlicher Dinge, wie das Singularisieren von Wörtern. "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

Scheint so. Ich bin neu in Ruby, und die anderen Antworten haben nicht das getan, was das OP verlangt hat, also habe ich es zum Laufen gebracht: D Korrigieren Sie mich, wenn ich falsch liege, aber AFAIK modifiziert einen String durch Ändern des Strings [i] nicht in vielen Sprachen arbeiten?
Jeriko

3
Dies ist eine Ruby-spezifische Frage. Es spielt keine Rolle, ob string[i]es nicht in anderen Sprachen funktioniert. Bitte helfen Sie dabei, StackOverflow frei von solchen gehackten Antworten zu halten. Wir können nicht RTFM sagen, aber selbst ein kurzer Blick auf die StringDokumente hätte geholfen, eine Antwort wie diese zu vermeiden ...
Maček
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.