切片字符串跳过特定字符

slice string skip specific character

我在 python3 中有这样的字符串:

ab_cdef_ghilm__nop_q__rs

从一个特定的字符开始,根据索引位置我想在这个字符周围切片一个 window 每边 5 个字符。但是如果找到 _ 字符,它必须跳过并转到下一个字符。例如,在这个字符串中考虑字符 "i" 我想在 "i" 周围有一个 11 个字符的最终字符串,在它出现时总是跳过 _ 字符,就像输出这个:

 defghilmnop

考虑到我有很长的字符串,我想决定我想做这件事的索引位置。 在这种情况下 index=10 是否有一个命令可以跳过特定字符来裁剪特定大小的字符串?

目前我能做的是从字符串中删除 _,同时计算 _ 出现的次数,并使用它来定义中间索引位置的偏移,最后我裁剪 window 所需的大小,但我想要一些更具处理性的东西,所以如果每次他找到“_”时我都能跳起来,那就太完美了

情况B)索引=13 我想在这个索引的左边有 5 个字符,在右边有 5 个字符,去掉(abd 不计算)_ 字符所以有这个输出:

ghilmnopqrs

所以基本上,当索引对应于一个字符时,从它开始,而不是当索引对应于一个 _ 字符时,我们必须移动(向右移动到下一个字符,最后是一个 11 个字符的字符串. 长话短说,输出是 11 个字符,索引位置在中间。如果索引位置是 _ 我们必须跳过这个字符并考虑中间的字符(更近)。

我认为没有针对此的特定命令,但您可以构建自己的命令。

例如:

s = 'ab_cdef_ghilm__nop_q__rs'

def get_slice(s, idx, n=5, ignored_chars='_'):
    if s[idx] in ignored_chars:
        # adjust idx to first valid on right side:
        idx = next((i for i, ch in enumerate(s[idx:], idx) if ch not in ignored_chars), None)
        if idx is None:
            return ''

    d = {i: ch for i, ch in enumerate(s) if ch not in ignored_chars}
    if idx in d:
        keys = [k for k in d.keys()]
        idx = keys.index(idx)
        return ''.join(d[k] for k in keys[max(0, idx-n):min(idx+n+1, len(s))])

print(get_slice(s, 10, 5, '_'))
print(get_slice(s, 13, 5, '_'))

打印:

defghilmnop
ghilmnopqrs

万一print(get_slice(s, 1, 5, '_')):

abcdefg

编辑:添加了对起始索引等于忽略字符的检查。

您定义了一个函数 split 如下所示,它将拆分一个字符串,使得它在左侧和右侧给出的字符数不是“_”

st = "ab_cdef_ghilm__nop_q__rs"

def slice(st, ind, c_count):
    cp = [char!="_" for char in st]
    for i in range(len(st)):
        if sum(cp[ind:ind+i]) == c_count:
            break
    right = ind + i
    for i in range(len(st)):
        if sum(cp[ind-i:ind]) == c_count:
            break
    left = ind - i

    return st[left:right+1]

slice(st, 10, 5)