Контекстно-зависимое разбиение строки в Python - PullRequest
4 голосов
/ 27 января 2012

Извинения, если это излишне, но довольно глубокий поиск промежутков не выявил здесь ничего уместного.

У меня есть строка из (химической) базы данных, где разделители (запятые) иногда встречаются в элементах, которые янадеюсь разделить.Пример строки:

s = '2-Methyl-3-phythyl-1,4-naphthochinon,Vitamin, K1,Antihemorrhagic vitamin'

Правильное разделение в этом случае даст

splitS = ['2-Methyl-3-phythyl-1,4-naphthochinon', 'Vitamin, K1', 'Antihemorrhagic vitamin']

Я считаю, что самый точный способ, которым я могу это разработать, - разделить запятые, которые неесть пробел рядом с запятой, и которые далее не окружены 2 числами.Это оставило бы такие экземпляры, как '1,4' и 'Vitamin, K1', но разбило строку на правильные 3 химических названия.

Я пытался использовать RE безуспешно.Я могу опубликовать кое-что из того, что я пробовал, но это в значительной степени бесполезно.Помощь очень ценится.

РЕДАКТИРОВАТЬ: должны были включить это первоначально.Благодаря некоторому моему взлому и более элегантному решению @Borealid я правильно определил места для разделения, но получаю отвратительный вывод, такой как

>>> s = '2-Methyl-3-phythyl-1,4-naphthochinon,Vitamin, K1,Antihemorrhagic vitamin'
>>> pat = re.compile("([^\d\s],[^\d\s])|([^\s],[^\d\s])|([^\d\s],[^\s])")
>>> re.split(pat, s)
['2-Methyl-3-phythyl-1,4-naphthochino', 'n,V', None, None, 'itamin, K', None, '1,A', None, 'ntihemorrhagic vitamin']

Кажется, что должен быть способсначала определите правильные запятые для разделения, затем разделите запятую only , чтобы избежать искажения имен.

Еще раз спасибо

Ответы [ 3 ]

5 голосов
/ 27 января 2012

Вы можете получить это поведение, используя lookaround , чтобы вы соответствовали только запятым, которые соответствуют вашему объяснению:

(?<!\d),(?! )|(?<=\d),(?![\d ])

И, похоже, у вас правильное поведение для примера: строка:

>>> re.split(r'(?<!\d),(?! )|(?<=\d),(?![\d ])', s)
['2-Methyl-3-phythyl-1,4-naphthochinon', 'Vitamin, K1', 'Antihemorrhagic vitamin']

Вот объяснение:

 (?<!\d),   # match a comma that is not preceeded by a digit...
 (?! )      # ... as long as it is not followed by a space
|           # OR
 (?<=\d),   # match a comma that is preceeded by a digit...
 (?![\d ])  # ... as long as it is not followed by a digit or a space

После написания объяснения я понял, что часть регулярного выражения (?<=\d) не нужна, так как она подразумеваетсяпервая часть регулярного выражения не совпадает, это означает, что вы можете сократить его до следующего и получить такое же поведение:

(?<!\d),(?! )|,(?![\d ])
0 голосов
/ 27 января 2012

У меня есть решение, но оно немного длинное. Хорошо, здесь мы идем:

s = '2-Methyl-3-phythyl-1,4-naphthochinon,Vitamin, K1,Antihemorrhagic vitamin'

Сначала давайте найдем все позиции всех запятых в строке (в all_commas) и позиции всех специальных запятых (в special_commas):

all_commas = [match.start() for match in re.finditer(r',', s)]
special_commas = [match.start()+1 for match in re.finditer(r'\d,\d|.,\s', s)]

Во-вторых, мы получаем разницу от этих позиций (в split_commas). Теперь у нас есть позиции, где мы собираемся разделить:

split_commas = set(all_commas) - set(special_commas)

Затем мы собираемся перебрать эти разделенные позиции и сохранить разделенные строки в splitS

splitS = []
start = -1
for end in sorted(split_commas) + [None]:
    splitS.append(s[start+1:end])
    start = end

Наконец, вот что мы получаем в splitS:

>>> splitS
['2-Methyl-3-phythyl-1,4-naphthochinon', 'Vitamin, K1', 'Antihemorrhagic vitamin']
0 голосов
/ 27 января 2012

Что-то вроде ([^\d\s],[^\d\s])|([^\s],[^\d\s])|([^\d\s],[^\s])?

Запятая с ((Номер на каждой стороне) или (номер на стороне хвоста, но не на стороне головы) или (номер на стороне головы, но не на стороне хвоста)) ".

Во всех случаях рядом с запятой не должно быть пробелов.

\d это «цифра». \s - это «пробел». [] - это класс символов - [^] - это инвертированный класс символов («соответствует символу, которого нет в последующем содержимом»)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...