Разделение строк в Python

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

  • Имеет правила нерегулярной иерархии. Первая строка следует другим правилам, чем остальная часть таблицы.
  • Иерархия жестко запрограммирована, имея не более 6 уровней. Что произойдет, если некоторым сообществам потребуется больше уровней?

В любом случае, можно получить имеющуюся у вас информацию, хотя и с использованием некрасивого запроса SQL. Вот оно:

select
  j.*  
from (
  select -- select the initial location
  from locations l
  where name = 'Yorkshire'
  union
  select -- select all children locations
  from locations l
  join locations r 
    on (l.continent is null and l.name = r.continent)
    or (l.continent is not null and l.country is null and l.name = r.country)
    or (l.continent is not null and l.country is not null and l.admin1 is null and l.name = r.admin1)
    or (l.continent is not null and l.country is not null and l.admin1 is not null and l.admin2 is null and l.name = r.admin2)
    or (l.continent is not null and l.country is not null and l.admin1 is not null and l.admin2 is not null and l.city is null and l.name = r.city)
  where l.name = 'Yorkshire'
  ) x    
join jobs j on j.location_id = x.id

Примечание : этот запрос не использует CTE (Common Table Expressions), поэтому он подходит для MySQL 5.x, а также MySQL 8.x. ]

7
задан Jouni K. Seppänen 24 October 2008 в 17:42
поделиться

6 ответов

Вот упрощенное решение, которое работает с Вашим тестовым входом:

import re
re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+',s)

Это возвратит любой код, который соответствует также

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

Это работает с Вашим примером, но могло бы перестать работать для многих реальных строк, с которыми можно встретиться. Например, Вы не сказали, что Вы ожидаете с незакрытыми скобками или кавычками, или как Вы хотите, чтобы одинарные кавычки или символы ESC работали. Для простых случаев, тем не менее, вышеупомянутое могло бы быть достаточно хорошим.

8
ответ дан 6 December 2019 в 21:21
поделиться

Завершать сообщение Bryan и соответствовать точно ответу:

>>> import re
>>> txt = 'this is [bracket test] "and quotes test "'
>>> [x[1:-1] if x[0] in '["' else x for x in re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+', txt)]
['this', 'is', 'bracket test', 'and quotes test ']

Не поймите неправильно целый используемый синтаксис: Это не несколько statments на одной строке, но единственном функциональном statment (больше bugproof).

5
ответ дан 6 December 2019 в 21:21
поделиться

Вот упрощенный синтаксический анализатор (протестированный против Вашего входа в качестве примера), который представляет шаблон разработки состояния.

В реальном мире Вы, вероятно, хотите создать реальный синтаксический анализатор с помощью чего-то как СГИБ.

class SimpleParser(object):

    def __init__(self):
        self.mode = None
        self.result = None

    def parse(self, text):
        self.initial_mode()
        self.result = []
        for word in text.split(' '):
            self.mode.handle_word(word)
        return self.result

    def initial_mode(self):
        self.mode = InitialMode(self)

    def bracket_mode(self):
        self.mode = BracketMode(self)

    def quote_mode(self):
        self.mode = QuoteMode(self)


class InitialMode(object):

    def __init__(self, parser):
        self.parser = parser

    def handle_word(self, word):
        if word.startswith('['):
            self.parser.bracket_mode()
            self.parser.mode.handle_word(word[1:])
        elif word.startswith('"'):
            self.parser.quote_mode()
            self.parser.mode.handle_word(word[1:])
        else:
            self.parser.result.append(word)


class BlockMode(object):

    end_marker = None

    def __init__(self, parser):
        self.parser = parser
        self.result = []

    def handle_word(self, word):
        if word.endswith(self.end_marker):
            self.result.append(word[:-1])
            self.parser.result.append(' '.join(self.result))
            self.parser.initial_mode()
        else:
            self.result.append(word)

class BracketMode(BlockMode):
    end_marker = ']'

class QuoteMode(BlockMode):
    end_marker = '"'
1
ответ дан 6 December 2019 в 21:21
поделиться

Вот более процедурный подход:

#!/usr/bin/env python

a = 'this is [bracket test] "and quotes test "'

words = a.split()
wordlist = []

while True:
    try:
        word = words.pop(0)
    except IndexError:
        break
    if word[0] in '"[':
        buildlist = [word[1:]]
        while True:
            try:
                word = words.pop(0)
            except IndexError:
                break
            if word[-1] in '"]':
                buildlist.append(word[:-1])
                break
            buildlist.append(word)
        wordlist.append(' '.join(buildlist))
    else:
        wordlist.append(word)

print wordlist
0
ответ дан 6 December 2019 в 21:21
поделиться

Ну, я встретился с этой проблемой довольно много раз, которая привела меня писать свою собственную систему для парсинга любого вида синтаксиса.

Результат этого может быть найден здесь; обратите внимание, что это может быть излишеством, и оно предоставит Вам что-то, что позволяет Вам проанализировать операторы и со скобками и с круглыми скобками, одинарными и двойными кавычками, столь вложенными, как Вы хотите. Например, Вы могли проанализировать что-то вроде этого (пример, записанный в языке Common LISP):

(defun hello_world (&optional (text "Hello, World!"))
    (format t text))

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

Идея является в основном настраиваемой реализацией Конечного автомата, который создает познаковое абстрактное синтаксическое дерево. Я рекомендую посмотреть на исходный код (см. ссылку выше), так, чтобы можно было понять то, как сделать это. Это способно через регулярные выражения, но попытку, пишущий систему с помощью REs и затем пытаясь расширить его (или даже понять его) позже.

0
ответ дан 6 December 2019 в 21:21
поделиться

Работы для кавычек только.

rrr = []
qqq = s.split('\"')
[ rrr.extend( qqq[x].split(), [ qqq[x] ] )[ x%2]) for x in range( len( qqq ) )]
print rrr
-2
ответ дан 6 December 2019 в 21:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: