Python - Как разбить строку на не алфавитно-цифровую, но сохранить любую не алфавитно-цифровую - PullRequest
0 голосов
/ 17 марта 2020

string = "Tes.t / & hi - &"

Ожидаемый результат - ["Tes", "." , "t", "", "/", "&", "hi", "-", "&"]

или

Ожидаемый результат - ["Tes", " «. , "t", "/ &", "hi", "- &"]

Предпочтительно последний вывод будет лучше, но любой из них будет работать отлично.

Ответы [ 3 ]

1 голос
/ 17 марта 2020

Код

def splitnonalpha(s):
    """Split whenever the type of following characater is different (i.e. alpha or non-alpha)"""

    current = s[0]
    result = []
    for pos in range(1, len(s)):
        if s[pos].isalpha() and current[-1].isalpha():
            current += s[pos]  # same type as previous
        elif not s[pos].isalpha() and not current[-1].isalpha():
            current += s[pos]   # same type as previous
        else:
            # Different type-->store current, and reset to current character
            result.append(current)
            current = s[pos]

    if current:
        result.append(current)

    return result

Тест

s = "Tes.t / &hi-&"
print(splitnonalpha(s))

Выход

['Tes', '.', 't', ' / &', 'hi', '-&']
1 голос
/ 17 марта 2020

Вы можете попробовать что-нибудь, где вы проверите, находится ли символ в ascii_letters или нет, и добавить его к той же строке или к другой в зависимости от этого. Это может выглядеть так:

from string import ascii_letters
import sys
from typing import List

def main(input_string: str) -> List[str]:

    output = []
    sub_string = ''
    last_was_ascii = None

    for char in input_string:
        char_is_ascii = char in ascii_letters
        if last_was_ascii is None or char_is_ascii == last_was_ascii:
            sub_string += char
        else:
            output.append(sub_string)
            sub_string = char
        last_was_ascii = char_is_ascii
    output.append(sub_string)

    print(output)

if __name__ == "__main__":
    main(*sys.argv[1:])

При вводе командной строки python example_file.py "Tes.t / &hi-&" будет напечатано ['Tes', '.', 't', ' / &', 'hi', '-&'], то есть второй пример, который вы перечислили.

Это немного многословно, однако хитрость

0 голосов
/ 17 марта 2020

Одним из решений является использование регулярных выражений:

  1. найти все буквенно-цифровые:

    an = re.findall("[a-zA-Z0-9]+", s)
    
  2. найти все не буквенно-цифровые:

    non_an = re.findall("[^a-zA-Z0-9]+", s)
    
  3. застегните молнию:

    ziped = zip(an, non_an)
    
  4. выровняйте молнию:

    flat = sum(ziped, ())
    

или в одна строка:

sum(zip(re.findall("[a-zA-Z0-9]+", s), re.findall("[^a-zA-Z0-9]+", s)), ())

, чтобы охватить случаи, которые включают больше буквенно-цифровых, чем не буквенно-цифровых (или наоборот), используют itertools.zip_longest () и сбрасывают нули:

from itertools import zip_longest
[x for x in sum(zip_longest(re.findall("\w+", s), re.findall("[\W]+", s)), ()) if x]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...