Используемая вами модель базы данных страдает от двух основных проблем:
В любом случае, можно получить имеющуюся у вас информацию, хотя и с использованием некрасивого запроса 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. ]
Вот упрощенное решение, которое работает с Вашим тестовым входом:
import re
re.findall('\[[^\]]*\]|\"[^\"]*\"|\S+',s)
Это возвратит любой код, который соответствует также
Это работает с Вашим примером, но могло бы перестать работать для многих реальных строк, с которыми можно встретиться. Например, Вы не сказали, что Вы ожидаете с незакрытыми скобками или кавычками, или как Вы хотите, чтобы одинарные кавычки или символы ESC работали. Для простых случаев, тем не менее, вышеупомянутое могло бы быть достаточно хорошим.
Завершать сообщение 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).
Вот упрощенный синтаксический анализатор (протестированный против Вашего входа в качестве примера), который представляет шаблон разработки состояния.
В реальном мире Вы, вероятно, хотите создать реальный синтаксический анализатор с помощью чего-то как СГИБ.
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 = '"'
Вот более процедурный подход:
#!/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
Ну, я встретился с этой проблемой довольно много раз, которая привела меня писать свою собственную систему для парсинга любого вида синтаксиса.
Результат этого может быть найден здесь; обратите внимание, что это может быть излишеством, и оно предоставит Вам что-то, что позволяет Вам проанализировать операторы и со скобками и с круглыми скобками, одинарными и двойными кавычками, столь вложенными, как Вы хотите. Например, Вы могли проанализировать что-то вроде этого (пример, записанный в языке Common LISP):
(defun hello_world (&optional (text "Hello, World!"))
(format t text))
Можно использовать вложение, скобки (квадрат) и круглые скобки (круглые), единственные - и дважды заключенные в кавычки строки, и это очень расширяемо.
Идея является в основном настраиваемой реализацией Конечного автомата, который создает познаковое абстрактное синтаксическое дерево. Я рекомендую посмотреть на исходный код (см. ссылку выше), так, чтобы можно было понять то, как сделать это. Это способно через регулярные выражения, но попытку, пишущий систему с помощью REs и затем пытаясь расширить его (или даже понять его) позже.
Работы для кавычек только.
rrr = []
qqq = s.split('\"')
[ rrr.extend( qqq[x].split(), [ qqq[x] ] )[ x%2]) for x in range( len( qqq ) )]
print rrr