2016-11-22 3 views
0

Ich möchte alle Wörter (alphabetisch) in der Zeichenfolge in ihre Abkürzungen wie i18n konvertieren. Mit anderen Worten, ich möchte "extraordinary" in "e11y" ändern, da zwischen dem ersten und dem letzten Buchstaben in "extraordinary" 11 Zeichen stehen. Es funktioniert mit einem einzelnen Wort in der Zeichenfolge. Aber wie kann ich das Gleiche für eine Mehrwort-Zeichenfolge tun? Und natürlich, wenn ein Wort <= 4 ist, hat es keinen Sinn, eine Abkürzung daraus zu machen.Stuck in Abkürzung Implementierung zu Ruby String

class Abbreviator 

    def self.abbreviate(x) 
    x.gsub(/\w+/, "#{x[0]}#{(x.length-2)}#{x[-1]}") 
    end 

end 

Test.assert_equals(Abbreviator.abbreviate("banana"), "b4a", Abbreviator.abbreviate("banana")) 
Test.assert_equals(Abbreviator.abbreviate("double-barrel"), "d4e-b4l", Abbreviator.abbreviate("double-barrel")) 
Test.assert_equals(Abbreviator.abbreviate("You, and I, should speak."), "You, and I, s4d s3k.", Abbreviator.abbreviate("You, and I, should speak.")) 

Antwort

1
def short_form(str) 
    str.gsub(/[[:alpha:]]{4,}/) { |s| "%s%d%s" % [s[0], s.size-2, s[-1]] } 
end 

Die Regex liest, "Spiel vier oder mehr Buchstaben".

short_form "abc"   # => "abc" 
short_form "a-b-c"  #=> "a-b-c" 
short_form "cats"   #=> "c2s" 
short_form "two-ponies-c" #=> "two-p4s-c" 
short_form "Humpty-Dumpty, who sat on a wall, fell over" 
    #=> "H4y-D4y, who sat on a w2l, f2l o2r" 
+0

Dank @KirillZhuravlov für die Kennzeichnung eines Fehlers, den ich gemacht habe. –

+1

Ich dachte anfangs, dass die Konvertierung nur auf Wörter oder Bindestriche angewendet wird. Ich habe meine Antwort geändert, um mit Strings umzugehen. –

5

Ihr Fehler ist, dass Ihre zweite Parameter eine -Ersatzzeichenfolge ist auf x (die ursprüngliche gesamte Zeichenfolge) als Ganzes funktioniert.

Anstatt die Form der Verwendung gsub wobei der zweite Parameter einen Substitutions String ist, verwenden, um die Form der gsub wo der zweite Parameter ist ein Block (aufgeführt, zum Beispiel, die dritte auf this page). Jetzt erhalten Sie jede Teilzeichenfolge in Ihrem Block und können auf , dass Teilzeichenfolge einzeln betrieben werden.

+0

Es hat mich dazu gebracht, es zu berücksichtigen, danke. –

1

würde ich etwas entlang der Linien von dieser Empfehlung:

class Abbreviator 
    def self.abbreviate(x) 
    x.gsub(/\w+/) do |word| 
     # Skip the word unless it's long enough 
     next word unless word.length > 4 
     # Do the same I18n conversion you do before 
     "#{word[0]}#{(word.length-2)}#{word[-1]}" 
    end 
    end 
end 
+0

Tests sind vorbei, danke! –

1

Die akzeptierte Antwort ist nicht schlecht, aber es kann sehr viel einfacher durch nicht passende Worte gemacht werden, die in erster Linie zu kurz sind:

def abbreviate(str) 
    str.gsub(/([[:alpha:]])([[:alpha:]]{3,})([[:alpha:]])/i) { "#{$1}#{$2.size}#{$3}" } 
end 

abbreviate("You, and I, should speak.") 
# => "You, and I, s4d s3k." 

Alternativ können wir verwenden und Lookbehind Lookahead, was die Regexp komplexer macht, aber die Substitution einfacher:

+0

Ich glaube, dass diese Antwort vollständiger ist –

+1

Die Frage ist nicht klar, welche Zeichen in der Zeichenfolge, die konvertiert wird, sein können. Sie können alphabetische Zeichen, alphanumerische Zeichen oder alle Zeichen sein, aber ich bezweifle, dass sie "Wortzeichen" ("\ w") wären, wenn man bedenkt, dass "_______" str.gsub (/ (\ w) (\ w { 3,}) (\ w) /) {"# {$ 1} # {$ 2.size} # {$ 3}"} # => "_5_" '. Wenn '" _5_ "' OK ist, warum nicht '" -5- "'? –

+0

@CarySwoveland OP benutzte '\ w' in ihrem eigenen Code, also machte ich einen deduktiven Sprung. –