Строка Python, разделенная на несколько разделителей - PullRequest
2 голосов
/ 16 июня 2019

С учетом строки: s = FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE

Символами-разделителями являются P, Q, D и E

Я хочу иметь возможность разбить строкуна этих символах.

На основе: Можно ли разбить строку на несколько разделителей по порядку?

У меня есть следующее

def splits(s,seps):
    l,_,r = s.partition(seps[0])
    if len(seps) == 1:
        return [l,r]
    return [l] + splits(r,seps[1:])

seps = ['P', 'D', 'Q', 'E']

sequences = splits(s, seps)

Это дает мне:

['FFFFRRFFFFFFF',
 'PRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLF',
 'RRFRRFFFFFFFFR',
 '',
 'E']

Как мы видим, вторая запись имеет много P.

Я хочу это вхождение символов между последним набором P, а не первым вхождением (т. Е. RFFFFFFFLF).

Кроме того, порядок вхождения символов-разделителей не является фиксированным.

Ищете решения / советы о том, как этого добиться?

Обновление: желаемый вывод, весь набор строк между этими разделителями (аналогично показанному на рисунке), но с соблюдением условия последнего вхождениякак указано выше

Обновление 2: ожидаемый результат

['FFFFRRFFFFFFF',
 'RFFFFFFFLF',   # << this is where the output differs
 'RRFRRFFFFFFFFR',
 '',
 '']   # << the last E is 2 consecutive E with no other letters, hence should be empty

Ответы [ 4 ]

2 голосов
/ 16 июня 2019

Звучит так, будто вы хотите разделить последовательность от появления первого символа до последнего.

([PDQE])(?:.*\1)?

Иметь попробуйте с разделенным шаблоном в regex101 и PHP Demo на 3v4l.org (должно быть похоже на Python).

1 голос
/ 16 июня 2019
import re

s = "FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE"

def get_sequences(s):
    seen_delimiters = {c: ('', None) for c in 'PDQE'}
    order = 0
    for g in re.finditer(r'(.*?)([PDQE]|\Z)', s):
        if g[2]:
            if seen_delimiters[g[2][0]][1] == None:
                seen_delimiters[g[2][0]] = (g[1], order)
                order += 1
    return seen_delimiters

for k, (seq, order) in get_sequences(s).items():
    print('{}: order: {} seq: {}'.format(k, order, seq))

Отпечатки:

P: order: 0 seq: FFFFRRFFFFFFF
D: order: 1 seq: RFFFFFFFLF
Q: order: 2 seq: RRFRRFFFFFFFFR
E: order: 3 seq: 

Обновление (для последовательностей печати и ограничителей):

import re
s = "FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE"
for g in re.finditer(r'(.*?)([PDQE]+|\Z)', s):
    print(g[1], g[2])

Отпечатки:

FFFFRRFFFFFFF PP
RRRRRRLLRLLRLLL PP
F PP
L PP
L PP
LF PP
FF P
FLR P
FFRRLLR P
F P
RFFFFFFFLF D
RRFRRFFFFFFFFR QEE
0 голосов
/ 16 июня 2019

Это решение итерирует разделители один за другим, поэтому вы можете контролировать порядок, в котором вы хотите применить каждый из них:

s = 'FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE'
spliters='PDQE'
for sp in spliters:
    if type(s) is str:
        s = s.split(sp)
    else: #type is list
        s=[x.split(sp) for x in s]
        s = [item for sublist in s for item in sublist if item != ''] #flatten the list

выход:

['FFFFRRFFFFFFF',
 'RRRRRRLLRLLRLLL',
 'F',
 'L',
 'L',
 'LF',
 'FF',
 'FLR',
 'FFRRLLR',
 'F',
 'RFFFFFFFLF',
 'RRFRRFFFFFFFFR']
0 голосов
/ 16 июня 2019

Используйте re.split с классом символов [PQDE]:

import re

s = 'FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE'    
sequences = re.split(r'[PQDE]', s)
print(sequences)

Выход:

['FFFFRRFFFFFFF', '', 'RRRRRRLLRLLRLLL', '', 'F', '', 'L', '', 'L', '', 'LF', '', 'FF', 'FLR', 'FFRRLLR', 'F', 'RFFFFFFFLF', 'RRFRRFFFFFFFFR', '', '', '']

Если вы хотите разделить на1 или более разделителей:

import re

s = 'FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE'    
sequences = re.split(r'[PQDE]+', s)
print(sequences)

Вывод:

['FFFFRRFFFFFFF', 'RRRRRRLLRLLRLLL', 'F', 'L', 'L', 'LF', 'FF', 'FLR', 'FFRRLLR', 'F', 'RFFFFFFFLF', 'RRFRRFFFFFFFFR', '']

Если вы хотите захватить разделители:

import re

s = 'FFFFRRFFFFFFFPPRRRRRRLLRLLRLLLPPFPPLPPLPPLFPPFFPFLRPFFRRLLRPFPRFFFFFFFLFDRRFRRFFFFFFFFRQEE'    
sequences = re.split(r'([PQDE])', s)
print(sequences)

Выход:

['FFFFRRFFFFFFF', 'P', '', 'P', 'RRRRRRLLRLLRLLL', 'P', '', 'P', 'F', 'P', '', 'P', 'L', 'P', '', 'P', 'L', 'P', '', 'P', 'LF', 'P', '', 'P', 'FF', 'P', 'FLR', 'P', 'FFRRLLR', 'P', 'F', 'P', 'RFFFFFFFLF', 'D', 'RRFRRFFFFFFFFR', 'Q', '', 'E', '', 'E', '']
...