2017-02-17 1 views
1

Ich habe folgende Strings:Regex: Wie alle Zeichen außer einem Wort/Sequenz eines Musters ersetzen?

"ft-2 MY AWESOME ft-12 APP" 
"MY AWESOME APP" 
"MY AWESOME APP ft-20" 

ich einige Änderungen machen wollen (titleization in diesem Fall) auf die Worte außer ft-<NUMBER> Teile. ft-<NUMBER> Wort kann überall erscheinen. Es kann mehrmals vorkommen oder gar nicht vorhanden sein. Nach dem String-Manipulation, sollte das Endergebnis wie folgt aussehen:

"ft-2 My Awesome ft-12 App" 
"My Awesome App" 
"My Awesome App ft-20" 

Ist es möglich, jede Regex in Ruby zu schreiben, die diese Transformation tun?

ich so versucht:

"ft-4 MY AWESOME ft-5 APP".gsub(/(?<=ft-\d\s).*/) { |s| s.titleize } 

Ich habe dies: ft-4 My Awesome Ft 5 App zurück.

+0

Haben Sie schon etwas probiert? –

+0

Ich versuchte es mit 'gsub', aber ich konnte nicht herausfinden, dass alle Zeichen außer dem Muster übereinstimmen. – Musaffa

+0

Bitte geben Sie den Code ein, den Sie ausprobiert haben. –

Antwort

1

Ihre (?<=ft-\d\s).* Muster passen zu jedem Ort, der mit ft-<digits><whitespace> vorangestellt ist, und dann paßt alle 0+ Zeichen außer Zeilenumbruch Zeichen, die Sie titleize.

Sie müssen ganze Wörter, die nicht mit ft-<NUMBER> Muster beginnen, abgleichen.Dann alles, was Sie brauchen, ist das Spiel zu downcase und nutzen es:

s.gsub(/\b(?!ft-\d)\p{L}+/) { | m | m.capitalize } 

Oder, wenn Sie es vorziehen, $1 Variable zu verwenden, eine Erfassungsgruppe hinzufügen:

s.gsub(/\b(?!ft-\d)(\p{L}+)/) { $1.capitalize } 

Siehe Ruby demo

Musterdetails:

  • \b - vor allem, behaupten die Position vor einem Buchstaben (denn das nächste raubend Muster \p{L} ist, die einen Brief übereinstimmt)
  • (?!ft-\d) - einen negativen Look-Ahead, die das Spiel schlägt fehl, wenn die nächsten zwei Buchstaben sind ft, die mit einem befolgt werden - und eine Ziffer
  • (\p{L}+) - eine Erfassungsgruppe passende Buchstaben 1+ (das mit $1 im Ersetzungsblock später Bezug genommen wird)

Das capitalize„liefert umgewandelt, um eine Kopie von str mit dem ersten Zeichen zu Großbuchstaben und der Rest zu Kleinbuchstaben ".

+0

Ist es möglich, den Rest als Satz statt einzelner Wörter mit '\ b' zu bekommen? 'titleize' edel behandelt kleine Wörter wie und von, in usw., wenn sie in der Mitte eines Satzes sind. Für "ft-5 MEINE AWESOME APP OF RAILS ft-20" möchte ich "ft-5 My Awesome App von Rails ft-20" bekommen. Hier wird 'von' behandelt, indem man einen Edelstein titalisiert, wenn er in der Mitte einer Wortgruppe steht. – Musaffa

+0

Sie müssen mit ihnen im negativen Lookahead umgehen, fürchte ich. Wie '\ b (?! Ft- \ d | (?: Aus? | In (?: Zu)? | At) \ b)' –

0

Ich bin nicht 100% sicher, was Sie wollen, aber ich denke, dass das, was Sie zu downcase wollen und dann titleize einen String

Ich habe etwas Ähnliches auf einem meiner Projekte

#lib/core_ext/string.rb 
class String 
    def my_titleize 
    humanize.gsub(/\b('?[a-z])/) { $1.capitalize } 
    end 
end 

humanize (options = {}) public Aktiviert das erste Wort, wandelt Unterstriche in Leerzeichen um und entfernt eine abschließende '_id', falls vorhanden. Wie titleize, ist dies für die Erstellung schöner Ausgabe gedacht.

Die Großschreibung des ersten Wortes kann deaktiviert werden, indem der optionale Parameter auf false gesetzt wird. Standardmäßig ist dieser Parameter wahr.

+0

Ruby 'String' hat keine' humanize' Methode. – mudasobwa

4
R =/
    [[:alpha:]]+ # match one or more uppercase or lowercase letters 
    (?=\s|\z) # match a whitespace or end of string (positive lookahead) 
    /x   # free-spacing regex definition mode 

def doit(str) 
    str.gsub(R) { |s| s.capitalize } 
end 

doit "ft-2 MY AWESOME ft-12 APP" 
    #=> "ft-2 My Awesome ft-12 App" 
doit "MY AWESOME APP" 
    #=> "My Awesome App" 
doit "MY AWESOME APP ft-20" 
    #=> "My Awesome App ft-20" 
Verwandte Themen