【问题标题】:If a specific string, A, is present at the begining and/or end of a string B, how do we remove A from B?如果特定字符串 A 出现在字符串 B 的开头和/或结尾,我们如何从 B 中删除 A?
【发布时间】:2019-11-02 02:58:16
【问题描述】:

我的问题类似,但与以下不同:

How do I remove a substring from the end of a string in Python?

假设我们有:

input = "baabbbbb_xx_ba_xxx_abbbbbba"

我们希望保留除末尾的 ba 和开头的 ba 之外的所有内容。

1) 直接strip() 失败

strip 将字符串视为一个集合。也就是说,strip 将删除以任意顺序出现的字母 ab。我们只想删除字符 ba,如果它们以 的确切顺序出现。此外,与strip 不同,我们只希望从字符串末尾删除零个或一个副本。 "x\n\n\n\n".strip() 将删除许多新行,而不仅仅是一个。

input = "baabbbbb_xx_ba_xxx_abbbbbba"
output = input.strip("ba")
print(output)
prints "_xx_ba_xxx_"

2) 直接replace() 失败

input = "xx_ba_xxx"
output = input.replace("ba", "")
print(output)
# prints `xx__xxx`

不酷;我们只想从字符串的开头和结尾删除序列“ba”,而不是中间。

3) 没关系

input = "baabbbbb_xx_ba_xxx_abbbbbba"
output = "ba".join(input.rsplit("ba", 1))
print(output)
# output==input

最后说明

解决方案必须是通用的:接受任意两个输入字符串的函数,其中一个可能是“ba”。不需要的前导和尾随字符串可能包含“.”、“*”和其他不适合在正则表达式中使用的字符。

【问题讨论】:

    标签: python python-3.x string


    【解决方案1】:

    我的解决方案使用基本散列,但是,请注意散列冲突。 让我知道这是否可以帮助您解决问题。

    import functools
    
    
    def strip_ed(pattern, string):
        # pattern is not a substring of string
        if len(pattern) > len(string):
            return -1
    
        base = 26
        # Hash codes for the beginning of the string
        string_hash_beginning = functools.reduce(lambda h, c: h * base + ord(c), string[:len(pattern)], 0)
        # Hash codes for the ending of the string
        string_hash_end = functools.reduce(lambda h, c: h * base + ord(c), string[-len(pattern):], 0)
        # Hash codes for the pattern
        pattern_hash = functools.reduce(lambda h, c: h * base + ord(c), pattern, 0)
        while True:
            if string_hash_beginning == string_hash_end and \
                    string_hash_beginning == pattern_hash and \
                    string[:len(pattern)] == pattern:
                return string[len(pattern):-len(pattern)]
            elif string_hash_beginning == pattern_hash and string[:len(pattern)] == pattern:
                return string[len(pattern):]
            elif string_hash_end == pattern_hash and string[-len(pattern):] == pattern:
                return string[:-len(pattern)]
            else:
                return string
    

    【讨论】:

      【解决方案2】:

      这似乎有效:

      def ordered_strip(whole, part):
          center = whole
          if whole.endswith(part):
              center = center[:-len(part)]
          if whole.startswith(part):
              center = center[len(part):]
          return center
      

      【讨论】:

      • 你的切片有一个倒退(如果len(part) == 0,你也有问题)。
      • 无论如何,这几乎只是在做你想要从字符串的一端删除子字符串的事情,但是做了两次,所以我不确定你希望在这里添加什么值您已经链接的问题。
      • if whole.startswith(part): center = center[:-len(part)] 部分应为center = center[len(part):]
      • 您已经修复了切片问题,但您仍然返回 '' 以获得 ordered_strip('asdf', '')。此外,因为您使用whole 而不是center 进行开始/结束检查,所以您为ordered_strip('ababa', 'aba') 返回''。根据您使用它的目的,第二个'' 结果可能是您想要的,但它与大多数 Python 字符串操作例程处理重叠匹配的方式不同。 (第一个'' 结果肯定不对。)
      猜你喜欢
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      相关资源
      最近更新 更多