2017-04-23 2 views
0

Verwenden von Ruby 2.4. Ich habe eine Reihe von Saiten. Ich möchte nicht-brechenden und brechenden Platz vom Ende jedes Elements in dem Array entfernen sowie mehrere aufeinanderfolgende Vorkommen von Leerraum durch einen einzelnen Leerraum ersetzen. Ich dachte, unter teh war die Art und Weise, aber ich erhalte eine FehlermeldungWie ersetze ich aufeinanderfolgende Vorkommen von Leerraum in jedem Element meines Arrays?

> words = ["1", "HUMPHRIES \t\t\t\t\t\t\t\t\t\t\t\t\t\t, \t\t\t\t\t\t\t\t\t\t\t\t\tJASON", "328", "FAIRVIEW, OR (US)", "US", "M", " 27 ", "00:27:30.00 \t\t\t\t\t\t\t\t\t\t\t \n"] 

> words.map{|word| word ? word.gsub!(/\A\p{Space}+|\p{Space}+\z/, '').gsub!(/[[:space:]]+/, ' ') : nil } 
NoMethodError: undefined method `gsub!' for nil:NilClass 
    from (irb):4:in `block in irb_binding' 
    from (irb):4:in `map' 
    from (irb):4 
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.2/lib/rails/commands/console.rb:65:in `start' 
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.2/lib/rails/commands/console_helper.rb:9:in `start' 
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:78:in `console' 
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.2/lib/rails/commands/commands_tasks.rb:49:in `run_command!' 
    from /Users/nataliab/.rvm/gems/ruby-2.4.0/gems/railties-5.0.2/lib/rails/commands.rb:18:in `<top (required)>' 
    from bin/rails:4:in `require' 
    from bin/rails:4:in `<main>' 

Wie kann ich richtig aufeinander folgende Vorkommen von Leerraum ersetzen sowie Streifen aus jedem Wort in dem Array aus?

+0

so etwas wie dieses versuchen: http://stackoverflow.com/questions/41306355/how-to-replace-the-characters-in- a-string – agm1984

+0

Danke, aber diese Antwort behandelt nicht, wie nicht-brechender/brechender Platz von den Enden jedes Wortes im Array entfernt wird. –

+0

@Natalia Können wir Ihre Frage etwas aufräumen? Entfernen Sie die irb-Eingabeaufforderungen "2.4.0: 003" usw.; Setzen Sie ein '#' vor die Ausgaben und korrigieren Sie Ihre Tippfehler. Vielen Dank. –

Antwort

0

Tun Sie es mit einfachen gsub nicht gsub!

words.map do |w| 
    #respond_to?(:gsub) if you are not sure that array only from strings 
    w.gsub(/(?<=[^\,\.])\s+|\A\s+/, '') if w.respond_to?(:gsub) 
end 

Da gsub!nil zurückkehren können, wenn nicht die Zeichenfolge ändern und dann versuchen Sie mit nilgsub! wieder zu tun. Deshalb erhalten Sie einen undefined method gsub!' for nil:NilClass Fehler.

Von gsub! Erklärung in Ruby doc:

Führt die Ersetzungen von String # gsub an Ort und Stelle, Rückkehr str oder nil, wenn keine Ersetzungen durchgeführt wurden. Wenn kein Block und kein Ersatz angegeben wird, wird stattdessen ein Enumerator zurückgegeben.

Wie erwähnt @CarySwoveland in den Kommentaren \s nicht geschützte Leerzeichen umgehen kann. Um damit umzugehen, sollten Sie [[:space:]] anstelle von \s verwenden.

+0

Ich verstehe nicht Ihre Code. Wenn es ausgeführt wird, ist 'self'' main' und 'main' hat keine Methode' gsub'. Es werden auch keine Leerzeichen entfernt (zB [Unicode'a non-break space] (https://www.cs.tut.fi/~jkorpela/chars/spaces.html) '\ 00A0') , eine Anforderung der Spezifikation. –

+0

@CarySwoveland Danke, es war ein Tippfehler mit 'gsub' Aufruf nach der letzten Bearbeitung.Problem war nicht in der Regex in dieser Frage, aber Sie haben recht - "\ s" passt nicht zum non-break Space, aber es ist einfach zu handhaben, wenn Sie '\ s' in' [[:: space:]] '' ändern – idej

0

können Sie verwenden, um die folgenden:

words.map { |w| w.gsub(/(?<=[^\,\.])\s+/,'') } 
#=> ["1", "HUMPHRIES, JASON", "328", "FAIRVIEW, 
#  OR(US)", "US", "M", " 27", "00:27:30.00"] 
0

Ich gehe davon aus, alle Leerzeichen und geschützte Leerzeichen am Sende jedes Strings werden entfernt werden und, was noch übrig ist, werden alle Teil von Leerzeichen und nicht Räume werden durch ein Leerzeichen ersetzt. (Natalia, wenn das nicht richtig ist, informieren Sie mich in einem Kommentar wissen.)

words = 
    ["1", 
    "HUMPHRIES \t\t\t\, \t\t\t\t\t\t\t\t\t\t\t\t\tJASON", 
    " M\u00A0 \u00A0", 
    " 27 ", 
    "00:27:30.00 \t\t\t\t\t\t\t\t\t\t\t \n"] 

R =/
    [[:space:]]  # match a POSIX bracket expression for one character 
    (?=[[:space:]]) # match a POSIX bracket expression for in a positive lookahead 
    |    # or 
    [[:space:]]+ # match a POSIX bracket expression one or more times 
    \z    # match end of string 
    /x    # free-spacing regex definition mode 

words.map { |w| w.gsub(R, '').gsub(/[[:space:]]/, ' ') } 
    #=> ["1", "HUMPHRIES , JASON", " M", " 27", "00:27:30.00"] 

Beachten Sie, dass die POSIX [[:space:]] enthält ASCII Leerzeichen und Unicode des non-breaking Leerzeichen, \u00A0.

Um zu sehen, warum die zweite gsub benötigt wird, beachten Sie, dass

words.map { |w| w.gsub(R, '') } 
    #=> ["1", "HUMPHRIES\t,\tJASON", " M", " 27", "00:27:30.00"] 
Verwandte Themen