【问题标题】:Returning all characters before the first underscore返回第一个下划线之前的所有字符
【发布时间】:2010-09-21 16:31:25
【问题描述】:

在 Python 中使用re,我想返回字符串中第一次出现下划线之前的所有字符。此外,我希望返回的字符串全部为大写并且没有任何非字母数字字符。

例如:

AG.av08_binloop_v6 = AGAV08
TL.av1_binloopv2   = TLAV1

我很确定我知道如何使用string.upper() 返回一个全部大写的字符串,但我确信有几种方法可以有效地删除.。任何帮助将不胜感激。我仍在缓慢但肯定地学习正则表达式。每个提示都会添加到我的笔记中以备将来使用。

为了进一步澄清,我上面的例子不是实际的字符串。实际的字符串如下所示:

AG.av08_binloop_v6

我想要的输出看起来像:

AGAV08

下一个例子也是一样的。字符串:

TL.av1_binloopv2

期望的输出:

TLAV1

再次感谢大家的帮助!

【问题讨论】:

    标签: python regex string


    【解决方案1】:

    即使没有re:

    text.split('_', 1)[0].replace('.', '').upper()
    

    【讨论】:

    • 就我个人而言,乍一看,我觉得这更具可读性和可理解性,因此我更愿意在我的代码库中阅读它而不是接受的答案。
    【解决方案2】:

    试试这个:

    re.sub("[^A-Z\d]", "", re.search("^[^_]*", str).group(0).upper())
    

    【讨论】:

    • +1“按规格”,看起来不错,但我不是正则表达式大师。编辑:我会将re.search 替换为re.match 并将初始^ 放在模式中(match 总是从字符串的开头开始并为此进行了优化)。
    • 虽然我喜欢其他答案的简单性,但我也希望我采用的任何解决方案对进一步的正则表达式探索有用。这个符合要求。谢谢秋葵!
    • 只是为了将来的知识,re.compile 将如何完成?我喜欢这种单线性质,但如果知道未来的知识会很好。
    • @durandal:a = re.compile(r'^A-Z\d')b = re.compile(r'[^_]*')re.sub(a, "", re.search(b, s).group(0).upper())(用描述性名称代替 a 和 b)。此处不需要原始字符串 (r"..."),但我更喜欢始终将它们用于正则表达式模式。
    • 实际上使用re.compile 创建正则表达式对象会使您编写的内容更加清晰,delnan(您只是将字符串表达式替换为编译后的表达式)。你实际上可以打电话给a.sub( "", b.search( s ).group(0).upper() )
    【解决方案3】:

    由于每个人都在给出他们最喜欢的实现,这里是我的不使用re

    >>> for s in ('AG.av08_binloop_v6', 'TL.av1_binloopv2'):
    ...     print ''.join(c for c in s.split('_',1)[0] if c.isalnum()).upper()
    ...
    AGAV08
    TLAV1
    

    我把.upper()放在了生成器的外面,所以它只被调用一次。

    【讨论】:

      【解决方案4】:

      您不必为此使用re。根据您的要求,简单的字符串操作就足够了:

      tests = """
      AG.av08_binloop_v6 = AGAV08
      TL.av1_binloopv2   = TLAV1
      """
      
      for t in tests.splitlines(): 
           print t[:t.find('_')].replace('.', '').upper()
      
      # Returns:
      # AGAV08
      # TLAV1
      

      或者如果你绝对必须使用re:

      import re 
      
      pat = r'([a-zA-Z0-9.]+)_.*'
      pat_re = re.compile(pat)
      
      for t in tests.splitlines():
          print re.sub(r'\.', '', pat_re.findall(t)[0]).upper()
      
      # Returns:
      # AGAV08
      # TLAV1
      

      【讨论】:

      • 虽然我同意正则表达式不能治愈癌症并且通常被过度使用,但它们是此类任务的可行选择。
      • 可行,是的。但是对于这样一个简单的任务来说过于复杂了。
      • Gumbo 的解决方案是一个可读性很强的单行。如果有人知道正则表达式的基础知识,那么它的作用就很清楚了。这不像是一个6k字符的怪物。
      【解决方案5】:

      他,只是为了好玩,在第一个下划线之前获取文本的另一种选择是:

      before_underscore, sep, after_underscore = str.partition('_')
      

      所以一行可以是:

      re.sub("[^A-Z\d]", "", str.partition('_')[0].upper())
      

      【讨论】:

        【解决方案6】:

        重新导入

        re.sub("[^A-Z\d]", "", yourstr.split('_',1)[0].upper())

        【讨论】:

          猜你喜欢
          • 2012-01-29
          • 1970-01-01
          • 2021-08-31
          • 1970-01-01
          • 2014-03-26
          • 1970-01-01
          • 1970-01-01
          • 2016-07-06
          • 2017-03-10
          相关资源
          最近更新 更多