Truncate string with Rails?

前端 未结 7 610
醉酒成梦
醉酒成梦 2021-01-31 07:40

I want to truncate a string as follows:

input:

string = \"abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa ffffdffffdffffdffffddd\"
相关标签:
7条回答
  • 2021-01-31 07:42

    This is the source code of String#truncate

    def truncate(truncate_at, options = {})
      return dup unless length > truncate_at
    
      options[:omission] ||= '...'
      length_with_room_for_omission = truncate_at - options[:omission].length
      stop = \
        if options[:separator]
          rindex(options[:separator], length_with_room_for_omission) ||      length_with_room_for_omission
        else
          length_with_room_for_omission
        end
    
       "#{self[0...stop]}#{options[:omission]}"
    end
    

    So, as for you case

    string.truncate(37, :omission => "...ffffffffd")
    
    0 讨论(0)
  • 2021-01-31 07:54

    Truncate with Custom Omission

    Similar to what some others have suggested here, you can use Rails' #truncate method and use a custom omission that is actually the last part of your string:

    string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa ffffdffffdffffdffffffffd"
    
    truncate(string, length: 37, omission: "...#{string[-5, 5]}")
    # => "abcd asfsa sadfsaf safsdaf aa...ffffffffd"
    

    Exactly what you wanted.

    Bonus Points

    You might want to wrap this up in a custom method called something like truncate_middle that does some fancy footwork for you:

    # Truncate the given string but show the last five characters at the end.
    #
    def truncate_middle( string, options = {} )
      options[:omission] = "...#{string[-5, 5]}"    # Use last 5 chars of string.
    
      truncate( string, options )
    end
    

    And then just call it like so:

    string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa ffffdffffdffffdffffffffd"
    
    truncate_middle( string, length: 37 )
    # => "abcd asfsa sadfsaf safsdaf aa...ffffffffd"
    

    Boom!

    Thanks for asking about this. I think it's a useful way to show a snippet of a longer piece of text.

    0 讨论(0)
  • 2021-01-31 07:57

    That's actually an interesting problem and you may want to solve it using javascript rather than ruby. Here is why, you're probably displaying this text on the screen somewhere, and you only have a certain amount of width available. So rather than having your link (or whatever text) cut down to a number of characters, what you really want is to make sure the text you're displaying never exceeds a certain width. How many characters can fit in a certain width depends on the font, spacing etc. (the css styles) you're using. You can make sure everything is ok if you're using a ruby-based solution, but it might all fall appart if you decide to change your styling later on.

    So, I recommend a javascript-based solution. The way I've handled it previously has been to use the jquery truncate plugin. Include the plugin in your app. And then hook in some javascript similar to the following every time the page loads:

    function truncateLongText() {
      $('.my_style1').truncate({
        width: 270,
        addtitle: true
      });
      $('.my_style2').truncate({
        width: 100
      });
    }
    

    Add in whatever other styles need to be truncatable and the width that they should respect, the plugin does the rest. This has the added advantage of having all your truncation logic for the whole app in one place which can be handy.

    0 讨论(0)
  • 2021-01-31 07:59

    Take a look at truncate, it partially does want you want. If you test whether it got trunctated or not, you could add some of the last part back after the truncated part.

    truncate("Once upon a time in a world far far away")
    # => "Once upon a time in a world..."
    
    truncate("Once upon a time in a world far far away", :length => 17)
    # => "Once upon a ti..."
    
    truncate("Once upon a time in a world far far away", :length => 17, :separator => ' ')
    # => "Once upon a..."
    
    truncate("And they found that many people were sleeping better.", :length => 25, :omission => '... (continued)')
    # => "And they f... (continued)"
    
    0 讨论(0)
  • 2021-01-31 08:03

    In the simplest case:

    string = "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa ffffdffffdffffdffffffffd"
    tr_string = string[0, 20] + "..." + string[-5,5]
    

    or

    def trancate(string, length = 20)
      string.size > length+5 ? [string[0,length],string[-5,5]].join("...") : string
    end
    
    # Usage
    trancate "abcd asfsa sadfsaf safsdaf aaaaaaaaaa aaaaaaaaaa ffffdffffdffffdffffffffd"
    #=> "abcd asfsa sadfsaf s...ffffffffd"
    trancate "Hello Beautiful World"
    #=> "Hello Beautiful World"
    trancate "Hello Beautiful World", 5
    #=> "Hello...World"
    
    0 讨论(0)
  • 2021-01-31 08:04

    This may not be the exact solution to your problem, but I think it will help put you in the right direction, with a pretty clean way of doing things.

    If you want "Hello, World!" to be limited to the first five letters, you can do:

    str = "Hello, World!"
    str[0...5] # => "Hello"
    

    If you want an ellipses, just interpolate it:

    "#{str[0...5]}..." #=> "Hello..."
    
    0 讨论(0)
提交回复
热议问题