LINUX.ORG.RU

[Python] Разбить строку на слова

 


0

0

Здравствуйте,

необходимо разбить строку на слова используя сделующие правила:

* Разделитель строк пробел

* Текст в двойных кавычках считается как отдельное слово

* В слове могут быть escape последовательности

То есть строка вида:

r'abc foo"" «„bar a\093d foo\ bar\ mode “ asdfa d \» df «'

должна быть преобразована в список:

['abc, 'foo', '»«', '»«', „bar“, 'a\093d', 'foo\ bar\ mode', '„asdfa d \\“ df »']

Можете мне помочь?



Последнее исправление: ConnorMcLaud (всего исправлений: 2)

Используй regexp. Напиши выражения для слов, строк и пустого места. Потом цикл, где проверяется соответствие и откусывается по кусочкам до полного уничтожения исходной строки.

vkos ★★
()

Не подходит? )))

s= r'abc foo"" «„bar a\093d foo\ bar\ mode “ asdfa d \» df «'
s.split(» ")

Ну тогда пиши свою софтинку )))

детекткд нападение тролей на питон )))

shelA
()
Ответ на: комментарий от vkos

>Используй regexp. Напиши выражения для слов, строк и пустого места.

Потом цикл, где проверяется соответствие и откусывается по кусочкам до

полного уничтожения исходной строки.

Порядок слов потеряется

ConnorMcLaud
() автор топика
Ответ на: комментарий от anonymous

>Модуль shlex примерно это делает.

Там есть два режима парсинга POSIX/не POSIX. Ни один из них мне полностью не подходит.

ConnorMcLaud
() автор топика
Ответ на: комментарий от ConnorMcLaud

Нет, проверять совпадение с началом строки. Если совпало и является словом/строкой — дописывать в список.

vkos ★★
()
Ответ на: комментарий от anonymous

>Написать самому ручками - делов на 15 минут.

Всемогущий анон. На словах оно всегда так.

ConnorMcLaud
() автор топика

В качестве решения написал вот такую процедуру:

def split_by_words(st):
    #word can be either delimeted by spaces or be put in double quotes
    #escape sequences should be also taken into account
    wordlist = []
    sepatators = [' ']
    quotes = ['"']
    escapes = ['\\']
    state = dict(in_none = 0, in_word=1, in_quotes=2)
    escape_state = False
    current_word = ''
    current_state = state['in_none']

    for index, char in enumerate(st):
        if current_state == state['in_none']:
            if char in quotes:
                current_state = state['in_quotes']
            elif char in escapes:
                escape_state = True
                current_state = state['in_word']
            elif char in sepatators:
                current_state = state['in_none']
            else:
                current_state = state['in_word']
        elif current_state == state['in_word']:
            if escape_state:
                escape_state = False
            else:
                if char in sepatators:
                    wordlist.append(current_word)
                    current_word = ''
                    current_state = state['in_none']
                elif char in quotes:
                    wordlist.append(current_word)
                    current_word = ''
                    current_state = state['in_quotes']
                elif char in escapes:
                    escape_state = True
        elif current_state == state['in_quotes']:
            if escape_state:
                escape_state = False
            else:
                if char in quotes:
                    current_word += char
                    wordlist.append(current_word)
                    current_word = ''
                    current_state = state['in_none']
                elif char in escapes:
                    escape_state = True

        if current_state != state['in_none']:
            current_word += char
            if index == len(st)-1 and current_word:
                wordlist.append(current_word)

    return wordlist

ConnorMcLaud
() автор топика
Ответ на: комментарий от ConnorMcLaud

В качестве решения написал вот такую процедуру:

OMG! А так не проще ;)

def ParseW(Str):
    prevCh = ''
    words = ['']
    inQuote = False
   
    for Ch in Str:
        if(Ch==' ') and (prevCh!='\\') and (not inQuote):
            if(len(words[len(words)-1])!=0):
                words.append('')
        else:
            if(Ch=='"') and (prevCh!='\\') and (not inQuote):
                if(len(words[len(words)-1])!=0):
                    words.append('')
                words[len(words)-1] += Ch
                inQuote = True
            elif(Ch=='"') and (prevCh!='\\') and (inQuote):
                words[len(words)-1] += Ch
                words.append('')
                inQuote = False
            else:
                words[len(words)-1] += Ch
        prevCh = Ch

    if(len(words[-1:][0])==0):
        words.pop()
    
    return words
    
print ParseW(r'abc foo"" ""bar a\093d foo\ bar\ mode " asdfa d \" df "')
shelA
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.