【问题标题】:Extract substring from index 0 up to searched character从索引 0 到搜索到的字符提取子字符串
【发布时间】:2011-09-27 18:44:09
【问题描述】:

我有一个名为user 的对象。我可以通过user.name得到它的名字,它的值有名字和姓氏如Jon Doe。抓住第一个字符直到空格字符的最有效和最优雅的方法是什么,以便我得到Jon

【问题讨论】:

  • 对于 hack 这将起作用(顺便说一句,它属于 User 类,所以你说 user.first_namenot user.name.split.first),但我认为你应该考虑构建 first_name 和 @将 987654329@ 功能添加到 User 类中,而不是依赖未指定的格式,这可能会导致错误。即(您应该将它们保留为单独的属性,然后将它们合并为名称:class User; def name; "#{first_name} #{last_name}" end end

标签: ruby string substring


【解决方案1】:

我会说:

s.split[0] # s = user.name

s.split.first

它们都将空格上的字符串拆分为字符串数组并返回第一个元素。即使只给出一个名字而不是名字和姓氏,它仍然可以工作。

【讨论】:

    【解决方案2】:

    以下将在空格上拆分字符串,并输出第一个元素(在您的情况下,这将是名字)。

    user.name.split[0]
    

    【讨论】:

      【解决方案3】:
      $`
      

      正是您正在寻找的。​​p>

      "John Doe" =~ / /
      $` # => "John"
      

      它也比 Knut 的答案中列出的替代方案更快:

      require 'benchmark'
      
      TEST_LOOPS = 10_000_000
      NAME = 'Jon Doe the third'
      
      #~ p NAME.split[0]
      #~ p NAME.split.first
      #~ p NAME[/^\S*/]
      #~ p NAME.split(/\s/, 2).first
      #~ p NAME.split(/\s/, 2)[0]
      #~ p NAME.split(' ', 2)[0]
      #~ exit
      
      Benchmark.bmbm(10) {|b|
      
        b.report('[0]') {
         TEST_LOOPS.times { 
            NAME.split[0]
         }            #Testloops
        }             #b.report
      
        b.report('[0]2regex') {
         TEST_LOOPS.times { 
            NAME.split(/\s/, 2)[0]
         }            #Testloops
        }             #b.report
        b.report('[0]2string') {
         TEST_LOOPS.times { 
            NAME.split(' ', 2)[0]
         }            #Testloops
        }             #b.report
      
      b.report('first') {
         TEST_LOOPS.times { 
            NAME.split.first
         }            #Testloops
        }             #b.report
        b.report('first2regex') {
         TEST_LOOPS.times { 
            NAME.split(/\s/, 2).first
         }            #Testloops
        }             #b.report
        b.report('first2string') {
         TEST_LOOPS.times { 
            NAME.split(' ', 2).first
         }            #Testloops
        }             #b.report
        b.report('regex') {
         TEST_LOOPS.times { 
            NAME[/^\S*/]
         }            #Testloops
        }             #b.report
      
        b.report('dollar backtick') {
         TEST_LOOPS.times { 
            NAME =~ / /
            $`
         }            #Testloops
        }             #b.report
      
      } #Benchmark
      

      给予

      Rehearsal ---------------------------------------------------
      [0]              30.453000   0.797000  31.250000 ( 31.311608)
      [0]2regex        21.094000   0.000000  21.094000 ( 23.651419)
      [0]2string       19.188000   0.000000  19.188000 ( 20.999215)
      first            34.187000   0.782000  34.969000 ( 39.935742)
      first2regex      24.078000   0.000000  24.078000 ( 26.813530)
      first2string     19.125000   0.000000  19.125000 ( 19.411310)
      regex            13.094000   0.000000  13.094000 ( 13.242792)
      dollar backtick  12.219000   0.000000  12.219000 ( 12.227719)
      ---------------------------------------- total: 175.017000sec
      
                            user     system      total        real
      [0]              30.859000   0.734000  31.593000 ( 33.809723)
      [0]2regex        20.891000   0.000000  20.891000 ( 21.156553)
      [0]2string       18.890000   0.000000  18.890000 ( 19.997051)
      first            32.516000   0.812000  33.328000 ( 36.216360)
      first2regex      22.000000   0.000000  22.000000 ( 22.853772)
      first2string     19.781000   0.000000  19.781000 ( 22.010805)
      regex            13.359000   0.000000  13.359000 ( 14.892417)
      dollar backtick  12.328000   0.000000  12.328000 ( 13.253315)
      

      【讨论】:

        【解决方案4】:

        我很好奇,最快的解决方案是什么。我的结果是the regex of Wayne

        关于拆分的一句话:如果您的名字有更多部分,您可能会在第一次拆分后停止。您可以使用

        String#split(/\s/, 2)
        

        我的基准:

        require 'benchmark'
        
        TEST_LOOPS = 10_000_000
        NAME = 'Jon Doe the third'
        
        #~ p NAME.split[0]
        #~ p NAME.split.first
        #~ p NAME[/^\S*/]
        #~ p NAME.split(/\s/, 2).first
        #~ p NAME.split(/\s/, 2)[0]
        #~ p NAME.split(' ', 2)[0]
        #~ exit
        
        Benchmark.bmbm(10) {|b|
        
          b.report('[0]') {
           TEST_LOOPS.times { 
              NAME.split[0]
           }            #Testloops
          }             #b.report
        
          b.report('[0]2regex') {
           TEST_LOOPS.times { 
              NAME.split(/\s/, 2)[0]
           }            #Testloops
          }             #b.report
          b.report('[0]2string') {
           TEST_LOOPS.times { 
              NAME.split(' ', 2)[0]
           }            #Testloops
          }             #b.report
        
        b.report('first') {
           TEST_LOOPS.times { 
              NAME.split.first
           }            #Testloops
          }             #b.report
          b.report('first2regex') {
           TEST_LOOPS.times { 
              NAME.split(/\s/, 2).first
           }            #Testloops
          }             #b.report
          b.report('first2string') {
           TEST_LOOPS.times { 
              NAME.split(' ', 2).first
           }            #Testloops
          }             #b.report
          b.report('regex') {
           TEST_LOOPS.times { 
              NAME[/^\S*/]
           }            #Testloops
          }             #b.report
        
          b.report('dollar backtick') {
           TEST_LOOPS.times { 
              NAME =~ / /
              $`
           }            #Testloops
          }             #b.report
        
        } #Benchmark
        

        结果:

        Rehearsal ---------------------------------------------------
        [0]              30.453000   0.797000  31.250000 ( 31.311608)
        [0]2regex        21.094000   0.000000  21.094000 ( 23.651419)
        [0]2string       19.188000   0.000000  19.188000 ( 20.999215)
        first            34.187000   0.782000  34.969000 ( 39.935742)
        first2regex      24.078000   0.000000  24.078000 ( 26.813530)
        first2string     19.125000   0.000000  19.125000 ( 19.411310)
        regex            13.094000   0.000000  13.094000 ( 13.242792)
        dollar backtick  12.219000   0.000000  12.219000 ( 12.227719)
        ---------------------------------------- total: 175.017000sec
        
                              user     system      total        real
        [0]              30.859000   0.734000  31.593000 ( 33.809723)
        [0]2regex        20.891000   0.000000  20.891000 ( 21.156553)
        [0]2string       18.890000   0.000000  18.890000 ( 19.997051)
        first            32.516000   0.812000  33.328000 ( 36.216360)
        first2regex      22.000000   0.000000  22.000000 ( 22.853772)
        first2string     19.781000   0.000000  19.781000 ( 22.010805)
        regex            13.359000   0.000000  13.359000 ( 14.892417)
        dollar backtick  12.328000   0.000000  12.328000 ( 13.253315)
        

        【讨论】:

        • 我可以将我的结果合并到您的答案中吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-11
        • 2016-01-01
        • 2019-07-22
        • 1970-01-01
        • 2011-10-13
        • 1970-01-01
        相关资源
        最近更新 更多