首页 > 解决方案 > 如果特定字符串 A 出现在字符串 B 的开头和/或结尾,我们如何从 B 中删除 A?

问题描述

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

如何从 Python 中的字符串末尾删除子字符串?

假设我们有:

input = "baabbbbb_xx_ba_xxx_abbbbbba"

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

1) 直接strip()失败

strip将字符串视为一个集合。也就是说,strip将删除字母ab以任何顺序出现。我们只想删除以确切顺序ba出现的字符。此外,与 不同的是,我们只希望从字符串末尾删除零个或一个副本。"x\n\n\n\n".strip() 将删除许多换行符,而不仅仅是一个。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”。不需要的前导和尾随字符串可能包含“ .”、“ *”和其他不适合在正则表达式中使用的字符。

标签: pythonpython-3.xstring

解决方案


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

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

推荐阅读