切片字符串跳过特定字符
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)
我在 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)