Wiem, jak podzielić ciąg w oparciu o wiele separatorów przy użyciu RE, jak w tym pytaniu: Split sznurki z wielu ogranicznikami?. Ale zastanawiam się, jak podzielić ciąg za pomocą zamówienia podanego na liście ograniczników, w których każdy podział wydarzyłby się tylko raz.

multiple_sep_split("hello^goo^dbye:cat@dog", ['^',':','@'])
>>> ['hello', 'goo^dbye', 'cat', 'dog']  #(note the extra carat)
multiple_sep_split("my_cat:my_dog:my:bird_my_python",[':',':','_'])
>>> ['my_cat','my_dog','my:bird','my_python']

Jedno podejście może być dopasowane do ograniczników, ale na tekście między ogranicznikami i zwrócić te grupy, ale czy istnieje inny sposób?

text_re = re.compile('(.+)^(.+):(.+)@(.+)') # get each group from here
0
ishikun 5 grudzień 2013, 07:28

2 odpowiedzi

Najlepsza odpowiedź

Jeśli rozumiem, o czym pytasz, po prostu chcesz serii string partition Operations: First partition na pierwszym separatoru, a następnie drugi itp. Do końca.

Oto metoda rekurencyjna (która nie używa Re):

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

Próbny:

a = 'hello^goo^dbye:cat@dog'

splits(a,['^',':','@'])
Out[7]: ['hello', 'goo^dbye', 'cat', 'dog']
2
roippi 5 grudzień 2013, 03:47

Wierzę, że twoje pytanie jest poważnie określone, ale przynajmniej daje wynik, który chcesz w przykładzie, który dałeś:

def split_at_most_once_each_and_in_order(s, seps):
    result = []
    start = 0
    for sep in seps:
        i = s.find(sep, start)
        if i >= 0:
            result.append(s[start: i])
            start = i+1
    if start < len(s):
        result.append(s[start:])
    return result

print split_at_most_once_each_and_in_order(
    "hello^goo^dbye:cat@dog", "^:@")

To zwraca ['hello', 'goo^dbye', 'cat', 'dog']. Jeśli absolutnie chcesz "być mądrym", patrzysz ;-)

2
Tim Peters 5 grudzień 2013, 03:49