【问题标题】:Analyzing string input until it reaches a certain letter on Python分析字符串输入,直到它到达 Python 上的某个字母
【发布时间】:2011-11-17 04:12:42
【问题描述】:

我在尝试编写程序的某个部分时需要帮助。 这个想法是一个人会输入一堆乱码,程序会读取它,直到它到达“!” (感叹号)例如:

input("Type something: ")

人员类型:wolfdo65gtornado!salmontiger223

如果我要求程序打印输入,它应该只打印 wolfdo65gtornado 并在到达“!”时剪切任何内容程序的其余部分是分析和计算字母,但那些部分我已经知道该怎么做了。我只需要第一部分的帮助。我一直在试图翻阅这本书,但似乎我遗漏了一些东西。

我在想,也许利用for 循环然后对其施加限制,但我无法弄清楚如何对某个字符的随机插补字符串输入进行分析,然后摆脱其余的。

如果您能提供帮助,我将不胜感激。谢谢!

【问题讨论】:

    标签: python string input edit


    【解决方案1】:

    内置的str.partition() 方法将为您完成这项工作。与str.split() 不同,它不会费心将str 的其余部分切割成不同的strs。

    text = raw_input("Type something:")
    left_text = text.partition("!")[0]
    

    说明

    str.partition() 返回一个包含字符串开头、分隔符和结尾的三元组。在这种情况下,[0] 获得了您想要的第一个项目。例如:

    "wolfdo65gtornado!salmontiger223".partition("!")
    

    返回

    ('wolfdo65gtornado', '!', 'salmontiger223')
    

    【讨论】:

    • 当然会,不同的是分区保留“!”数组中的字符(在这种情况下)(实际上它输出到列表而不是数组): >>> s.partition('!') ('wolfdo65gtornado', '!', 'salmontiger223') >>> s.split('!') ['wolfdo65gtornado', 'salmontiger223'] >>>
    • 我的意思是,如果有多个 "!" 字符,您将不会得到一个列表,其中每个字符都有拆分。
    • 好吧,是的,你会:s = "wolfdo!65gtornado!salmo!ntig!er223"s.split('!')['wolfdo', '65gtornado', 'salmo', 'ntig', 'er223'],如果你之后迭代它,你就不必跳到数组中的第二个位置,就像你使用 rpartition
    • 我说的是您使用str.partition() 来执行此操作的情况,而不是str.split()。这正是将str.partition() 添加到语言中的用例。
    • 好吧,在这个特殊的用例中,我认为没有理由使用 str.partition 而不是 str.split,但请随时启发我 - 它更快还是什么?
    【解决方案2】:
    >>> s = "wolfdo65gtornado!salmontiger223"
    >>> s.split('!')[0]
    'wolfdo65gtornado'
    >>> s = "wolfdo65gtornadosalmontiger223"
    >>> s.split('!')[0]
    'wolfdo65gtornadosalmontiger223'
    

    如果它没有遇到“!”字符,它只会抓取整个文本。如果你想在不匹配任何“”的情况下输出错误,你可以这样做:

    s = "something!something"
    if "!" in s:
      print "there is a '!' character in the context"
    else:
      print "blah, you aren't using it right :("
    

    【讨论】:

    • split() 函数对此应用程序无效。假设字符串有 10,000 个字符长。第 53 个字符是感叹号 !。如果你从左到右读取字符串,那么我们只要遇到分隔符!就可以停止我们只需要字符串的开头(前缀)。 split() 函数将继续运行。
    【解决方案3】:

    你想要itertools.takewhile()

    >>> s = "wolfdo65gtornado!salmontiger223"
    >>> '-'.join(itertools.takewhile(lambda x: x != '!', s))
    'w-o-l-f-d-o-6-5-g-t-o-r-n-a-d-o'
    
    
    
    >>> s = "wolfdo65gtornado!salmontiger223!cvhegjkh54bgve8r7tg"
    >>> i = iter(s)
    >>> '-'.join(itertools.takewhile(lambda x: x != '!', i))
    'w-o-l-f-d-o-6-5-g-t-o-r-n-a-d-o'
    >>> '-'.join(itertools.takewhile(lambda x: x != '!', i))
    's-a-l-m-o-n-t-i-g-e-r-2-2-3'
    >>> '-'.join(itertools.takewhile(lambda x: x != '!', i))
    'c-v-h-e-g-j-k-h-5-4-b-g-v-e-8-r-7-t-g'
    

    【讨论】:

    • 我有一个变量 f_name='file.txt' 使用你对 itertools.takewhile() 的宝贵想法,我尝试了这个 bck_f_name='backup'.join(itertools.takewhile(lambda x: x = = ".",f_name)) 期望得到 bck_f_name 为 'filebackup.txt' 但我无法实现这一点.....任何帮助 wud b 可观
    • 在性能方面,此解决方案比其他解决方案 .split().partition() 慢约 10 倍
    【解决方案4】:

    试试这个:

    s = "wolfdo65gtornado!salmontiger223"
    m = s.index('!')
    l = s[:m]
    

    【讨论】:

    • 如果字符串中没有!怎么办?然后引发异常ValueError
    • 令人惊讶的是,这个解决方案比.partition()的解决方案慢了一点
    【解决方案5】:

    解释接受的答案。

    拆分

    partition() 函数将列表中的字符串拆分为 3 个元素:

    mystring = "123splitABC"
    x = mystring.partition("split")
    print(x)
    

    将给予:

    ('123', 'split', 'ABC')

    像列表元素一样访问它们:

    print (x[0]) ==> 123

    print (x[1]) ==> 拆分

    print (x[2]) ==> ABC

    【讨论】:

      【解决方案6】:

      假设我们有:

      s = "wolfdo65gtornado!salmontiger223" + some_other_string
      

      s.partition("!")[0]s.split("!")[0] 如果some_other_string 包含一百万个字符串,每个字符串长度为一百万个字符,并用感叹号分隔,那么这两个字符串都会出现问题。我推荐以下内容。效率更高。

      import itertools as itts
      get_start_of_string = lambda stryng, last, *, itts=itts:\
                                str(itts.takewhile(lambda ch: ch != last, stryng))
      ###########################################################
      s = "wolfdo65gtornado!salmontiger223"
      start_of_string = get_start_of_string(s, "!")
      

      为什么itts=itts

      在函数体内部,例如get_start_of_stringitts 是全局的。
      itts 在函数被调用时进行评估,而不是在函数被定义时。
      考虑以下示例:

      color = "white"
      get_fleece_color = lambda shoop: shoop + ", whose fleece was as " + color + " as snow."
      
      print(get_fleece_color("Igor"))
      
      # [... many lines of code later...]
      
      color = "pink polka-dotted"
      print(get_fleece_color("Igor's cousin, 3 times removed"))
      

      输出是:

      Igor, whose fleece was white as snow.
      Igor's cousin, 3 times removed Igor, whose fleece was as pink polka-dotted as snow.
      

      【讨论】:

        【解决方案7】:

        您可以使用正则表达式提取字符串的开头,直到遇到第一个分隔符。

        import re
        
        slash_if_special = lambda ch:\
            "\\" if ch in "\\^$.|?*+()[{" else ""
        
        prefix_slash_if_special = lambda ch, *, _slash=slash_if_special: \
            _slash(ch) + ch
        
        make_pattern_from_char = lambda ch, *, c=prefix_slash_if_special:\
            "^([^" + c(ch) + "]*)"
        
        def get_string_up_untill(x_stryng, x_ch):
            i_stryng = str(x_stryng)
            i_ch = str(x_ch)
            assert(len(i_ch) == 1)
            pattern = make_pattern_from_char(ch)
            m = re.match(pattern, x_stryng)
            return m.groups()[0]
        

        上面代码的使用示例:

        s = "wolfdo65gtornado!salmontiger223"
        result = get_string_up_untill(s, "!")
        print(result)
        # wolfdo65gtornado
        

        【讨论】:

        • 运行所写的代码会在pattern = make_pattern_from_char(ch) 处抛出NameError
        • 令人惊讶的是,这个看起来笨重的解决方案只比.partition()慢2倍
        【解决方案8】:

        我们可以使用 itertools

        s = "wolfdo65gtornado!salmontiger223"
        result = "".join(itertools.takewhile(lambda x : x!='!' , s))
        
        >>"wolfdo65gtornado"
        

        【讨论】:

        • 这不是和其他答案之一一样吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-10
        • 1970-01-01
        • 1970-01-01
        • 2013-08-14
        • 2020-02-02
        • 2013-08-11
        • 1970-01-01
        相关资源
        最近更新 更多