【问题标题】:Chapter 7, Automate the boring stuff with Python, practice project: regex version of strip()第 7 章,用 Python 自动化无聊的东西,练习项目:strip() 的正则表达式版本
【发布时间】:2016-01-22 19:02:23
【问题描述】:

我正在阅读《用 Python 自动化无聊的东西》一书。在第 7 章,在项目实践中:strip() 的正则表达式版本,这是我的代码(我使用 Python 3.x):

def stripRegex(x,string):
import re
if x == '':
    spaceLeft = re.compile(r'^\s+')
    stringLeft = spaceLeft.sub('',string)
    spaceRight = re.compile(r'\s+$')
    stringRight = spaceRight.sub('',string)
    stringBoth = spaceRight.sub('',stringLeft)
    print(stringLeft)
    print(stringRight)

else:
    charLeft = re.compile(r'^(%s)+'%x)
    stringLeft = charLeft.sub('',string)
    charRight = re.compile(r'(%s)+$'%x)
    stringBoth = charRight.sub('',stringLeft)
print(stringBoth)

x1 = ''
x2 = 'Spam'
x3 = 'pSam'
string1 = '      Hello world!!!   '
string2 = 'SpamSpamBaconSpamEggsSpamSpam'
stripRegex(x1,string1)
stripRegex(x2,string2)
stripRegex(x3,string2)

这是输出:

Hello world!!!   
      Hello world!!!
Hello world!!!
BaconSpamEggs
SpamSpamBaconSpamEggsSpamSpam

所以,我的 strip() 正则表达式版本几乎可以作为原始版本使用。在原始版本中,无论您传入“Spam”、“pSam”、“mapS”、“Smpa”,输出始终为“BaconSpamEggs”... 那么如何在 Regex 版本中解决这个问题???

【问题讨论】:

  • 嗯,正则表达式并不神秘。所以你遇到的问题是你失去了对代码流的控制。
  • 什么是“原版”?
  • “原始版本”是本书第 6 章中解释的 strip() 默认方法。示例: spam = 'SpamSpamBaconSpamEggsSpamSpam') 输入: spam.strip('Spam') 或 spam.strip('Smap') 或 spam.strip('pSam') ...输出始终为: BaconSpamEggs跨度>
  • 我正在尝试解决同样的问题。完全理解“if”部分,但无法得到“else”。对于 %s 和 %x,re.compile 中的 % 符号是什么意思?

标签: python regex


【解决方案1】:
import re

def regexStrip(x,y=''):


if y!='':
    yJoin=r'['+y+']*([^'+y+'].*[^'+y+'])['+y+']*'
    cRegex=re.compile(yJoin,re.DOTALL)
    return cRegex.sub(r'\1',x)
else:
    sRegex=re.compile(r'\s*([^\s].*[^\s])\s*',re.DOTALL)
    return sRegex.sub(r'\1',x)

text='  spmaHellow worldspam'
print(regexStrip(text,'spma'))

【讨论】:

    【解决方案2】:

    您可以像这样检查正则表达式中的多个字符:

    charLeft = re.compile(r'^([%s]+)' % 'abc') 
    print charLeft.sub('',"aaabcfdsfsabca")
    >>> fdsfsabca
    

    或者更好的是,在单个正则表达式中完成:

    def strip_custom(x=" ", text):
        return re.search(' *[{s}]*(.*?)[{s}]* *$'.format(s=x), text).group(1)
    
    split_custom('abc', ' aaabtestbcaa ')
    >>> test
    

    【讨论】:

    • 这应该删除所有的 a、b 和 c 吗?为什么 a,b,c 还在输出中?
    • 只去掉左边的,右边也可以做类似的方法
    • 知道了 - 忘了strip 只做字符串的结尾
    【解决方案3】:

    我切换了参数,但从我的快速测试来看,这似乎有效。我给了它一个可选参数,默认为None

    def stripRegex(s,toStrip=None):
        import re
        if toStrip is None:
            toStrip = '\s'
        return re.sub(r'^[{0}]+|[{0}]+$'.format(toStrip), '', s)
    

    x1 = ''
    x2 = 'Spam'
    x3 = 'pSam'
    string1 = '      Hello world!!!   '
    string2 = 'SpamSpamBaconSpamEggsSpamSpam'
    
    print(stripRegex(string1)) # 'Hello world!!!'
    print(stripRegex(string1, x1)) # '      Hello world!!!   '
    print(stripRegex(string2, x2)) # 'BaconSpamEggs'
    print(stripRegex(string2, x3)) # 'BaconSpamEggs'
    

    【讨论】:

      【解决方案4】:

      我为此编写了两个不同的代码: 第一种方式:

      import re    
      def stripfn(string, c):
              if c != '':
                  Regex = re.compile(r'^['+ c +']*|['+ c +']*$')
                  strippedString = Regex.sub('', string)
                  print(strippedString)
              else:
                  blankRegex = re.compile(r'^(\s)*|(\s)*$')
                  strippedString = blankRegex.sub('', string)
                  print(strippedString)
      

      第二种方式:

      import re
      def stripfn(string, c):
          if c != '':
              startRegex = re.compile(r'^['+c+']*')
              endRegex = re.compile(r'['+c+']*$')
              startstrippedString = startRegex.sub('', string)
              endstrippedString = endRegex.sub('', startstrippedString)
              print(endstrippedString)
          else:
              blankRegex = re.compile(r'^(\s)*|(\s)*$')
              strippedString = blankRegex.sub('', string)
              print(strippedString)
      

      【讨论】:

        【解决方案5】:

        这似乎有效:

        def stripp(text, leftright = None):
            import re
            if leftright == None:
                stripRegex = re.compile(r'^\s*|\s*$')
                text = stripRegex.sub('', text)
                print(text)
            else:
                stripRegex = re.compile(r'^.|.$')
                margins = stripRegex.findall(text)
                while margins[0] in leftright:
                    text = text[1:]
                    margins = stripRegex.findall(text)
                while margins[-1] in leftright:
                    text = text[:-2]
                    margins = stripRegex.findall(text)
                print(text) 
        
        mo = '    @@@@@@     '
        mow = '@&&@#$texttexttext&&^&&&&%%'
        bla = '@&#$^%+'
        
        stripp(mo)
        stripp(mow, bla)
        

        【讨论】:

          【解决方案6】:

          这是我的版本:

              #!/usr/bin/env python3
          
          import re
          
          def strippp(txt,arg=''): # assigning a default value to arg prevents the error if no argument is passed when calling strippp()
              if arg =='':
                  regex1 = re.compile(r'^(\s+)')
                  mo = regex1.sub('', txt)
                  regex2 = re.compile(r'(\s+)$')
                  mo = regex2.sub('', mo)
                  print(mo)
              else:
                  regex1 = re.compile(arg)
                  mo = regex1.sub('', txt)
                  print(mo)
          
          text = '        So, you can create the illusion of smooth motion        '
          strippp(text, 'e')
          strippp(text)
          

          【讨论】:

            【解决方案7】:

            @rtemperv 的解决方案缺少当字符串以空格字符开始/结束但未提供此类字符以供删除时的情况。

            >>> var="     foobar"
            >>> var.strip('raf')
            '     foob'
            

            因此正则表达式应该有点不同:

            def strip_custom(x=" ", text):
                return re.search('^[{s}]*(.*?)[{s}]*$'.format(s=x), text).group(1)
            

            【讨论】:

              【解决方案8】:

              查看下面的代码

              from re import *
              check = '1'
              while(check == '1'):
                  string = input('Enter the string: ')
                  strToStrip = input('Enter the string to strip: ')
                  if strToStrip == '':                              #If the string to strip is empty
                      exp = compile(r'^[\s]*')                      #Looks for all kinds of spaces in beginning until anything other than that is found
                      string = exp.sub('',string)                   #Replaces that with empty string
                      exp = compile(r'[\s]*$')                      #Looks for all kinds of spaces in the end until anything other than that is found
                      string = exp.sub('',string)                   #Replaces that with empty string
                      print('Your Stripped string is \'', end = '')
                      print(string, end = '')
                      print('\'')
                  else:
                      exp = compile(r'^[%s]*'%strToStrip)           #Finds all instances of the characters in strToStrip in the beginning until anything other than that is found
                      string = exp.sub('',string)                   #Replaces it with empty string
                      exp = compile(r'[%s]*$'%strToStrip)           #Finds all instances of the characters in strToStrip in the end until anything other than that is found
                      string = exp.sub('',string)                   #Replaces it with empty string
                      print('Your Stripped string is \'', end = '')
                      print(string, end = '')
                      print('\'')
                  print('Do you want to continue (1\\0): ', end = '')
                  check = input()
              

              说明:

              • 字符类[]用于检查字符串中字符的各个实例。

              • ^用于检查要剥离的字符串中的字符是否在开头

              • $ 用于检查要剥离的字符串中的字符是否在末尾​​li>
              • 如果发现它们将被 empty string 替换为 sub()

              • * 用于匹配字符串中要删除的最大字符,直到找到除此之外的任何字符。

              • * 匹配 0 如果找到则没有实例,或者如果找到则匹配尽可能多的实例。

              【讨论】:

                【解决方案9】:
                #! python
                # Regex Version of Strip()
                import re
                def RegexStrip(mainString,charsToBeRemoved=None):
                    if(charsToBeRemoved!=None):
                        regex=re.compile(r'[%s]'%charsToBeRemoved)#Interesting TO NOTE
                        return regex.sub('',mainString)
                    else:
                        regex=re.compile(r'^\s+')
                        regex1=re.compile(r'$\s+')
                        newString=regex1.sub('',mainString)
                        newString=regex.sub('',newString)
                        return newString
                
                Str='   hello3123my43name is antony    '
                print(RegexStrip(Str))
                

                我认为这是一个相当舒适的代码,我发现插入符号 (^) 和美元 ($) 非常有效。

                【讨论】:

                  【解决方案10】:
                  import re
                  def strips(arg, string):
                      beginning = re.compile(r"^[{}]+".format(arg))        
                      strip_beginning = beginning.sub("", string)
                      ending = re.compile(r"[{}]+$".format(arg))
                      strip_ending = ending.sub("", strip_beginning)
                      return strip_ending
                  

                  功能条将删除任何“arg”所指的内容,而与出现无关

                  【讨论】:

                    【解决方案11】:

                    我相信这个正则表达式可能更容易理解:

                    import re
                    
                    strip_reg =  re.compile("\s*(.*?)\s*$")
                    strip_rep.search(<mystring>).group(1)
                    

                    它是如何工作的? 让它倒退。我们在字符串“\s*$”的末尾再找一个空格

                    “.*?”是一种特殊情况,您要求正则表达式查找要匹配的最少字符数。 (大多数时候,正则表达式会尽量发挥最大作用) 我们捕捉到了这一点。

                    我们尝试在我们捕获的组之前捕获零个或多个字符。

                    【讨论】:

                      【解决方案12】:

                      我的解决方案:

                      import re
                      
                      text = """
                       Write a function that takes a string and does the same thing as the strip() 
                      string method. If no other arguments are passed other than the string to 
                      strip, then whitespace characters will be removed from the beginning and 
                      end of the string. Otherwise, the characters specified in the second argu -
                      ment to the function will be removed from the string. 
                      """
                      
                      def regexStrip(text, charsToStrip=''):
                          if not charsToStrip:
                              strip = re.sub(r'^\s+|\s+$', '', text)
                          else:
                              strip = re.sub(charsToStrip, '', text)
                          return strip
                      
                      while True:
                          arg2 = input('Characters to strip: ')
                          print(regexStrip(text, arg2))
                      

                      【讨论】:

                        【解决方案13】:
                        #!usr/bin/python3
                        # my_strip.py - Perform strip function capability with regex
                        import re
                        
                        def myStrip(text, character=' '):
                            # Strip whitespace by default or user's argument 
                            stripCharRegex = re.compile(r'^[%s]*(.*?)[%s]*$'%(character,character)) # (.*?) Will match the least possible of any character (non-greedy)
                            return stripCharRegex.search(text).group(1)
                        

                        我正在使用单个正则表达式来匹配带空格或可选字符。如果您不了解 %s,请查看 String Interpolation。我们希望 (.*?) 匹配最少的可能(非贪婪)。去除 ?并检查一下。

                        【讨论】:

                          【解决方案14】:

                          以下是我尝试应用从 R.C. 的“清洁代码”中吸取的经验教训。 Martin 和 Al Sweigart 的“自动化无聊的东西”。干净代码的规则之一是编写小的函数,只做一件事。

                          def removeSpacesAndSecondString(text):
                              print(text)
                              stripSecondStringRegex = re.compile(r'((\w+)\s(\w+)?)')
                              for groups in stripSecondStringRegex.findall(text):
                                  newText = groups[1]
                              print(newText)
                          
                          def removeSpaces(text):
                              print(text)
                              stripSpaceRegex = re.compile(r'\s')
                              mo = stripSpaceRegex.sub('', text)
                              print(mo)
                          
                          text = '"  hjjkhk  "'
                          
                          if len(text.split()) > 1:
                              removeSpacesAndSecondString(text)
                          else:
                              removeSpaces(text)
                          

                          【讨论】:

                            猜你喜欢
                            • 2021-11-03
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2019-10-09
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多