Closed rominf closed 5 years ago
Можно так преобразовывать:
result = text[slice(*match.span)]
(примерно так же в этом ответе я делал https://ru.stackoverflow.com/a/889854/1365)
Как вариант можно добавить в класс span
поля (property) start
и stop
, тогда span
можно будет использовать в качестве индекса без преобразования в объект slice
.
@insolor, спасибо, не обратил внимание, что это namedtuple
. Но всё равно - не красиво.
@rominf насчет namedtuple не могу сказать (исходники не смотрел). Главное что iterable, а все что iterable можно передавать в функции через звездочку.
Спасибо за пуллреквест, мне кажется это лишнее, пользователю предлагается писать явно
match = matches[0]
start, stop = match.span
result = text[start:stop]
@alexanderkuk, это не PR, это issue)
Но почему? Это же реально частое действие. Если можно сократить 3 строчки до 1 почему бы этого не сделать?
Здесь я писал про Span.to_slice
, но обсуждение перешло в Match.text
. Можно же при извлечении сохранить текст в приватную переменную, а в property
Match.text
делать то, что описано.
Почему
Незначительное уменьшение код, я вижу сокращение одной строчки
match = matches[0]
start, stop = match.span
result = text[start:stop]
против
match = matches[0]
result = text[to_slice(match.span)]
Это же реально частое действие
На самом деле нет. Выделять сырые подстроки нужно обычно для отладки, для этого есть https://github.com/natasha/ipymarkup . Дальше обычно текст нужно структурировать и нормализовывать "Владимира Путина" -> first:владимир last:путин, сырые строки уже не используются
Ладно, я неправильно начал обсуждение. Забудьте про всё, что я писал раньше. Речь идёт не о Span
, а о выделении текста (заголовок после этого поменяю).
Реальный пример. Мне надо находить названия организаций с веб-страниц (без ООО|ОАО|...
и кавычек). Я захожу на главную, regexp-ом нахожу строку copyright, потом скармливаю её Наташе. Для того, чтобы никого не рекламировать и упростить код, скормлю другую строку. Spacy не умеет в русский язык пока, но хорошо справляется с недеструктивной токенизацией. Внизу сравнение.
text = 'ОАО "Ололо! Еда"'
from natasha import OrganisationExtractor
matches = extractor(text)
match = matches[0]
''.join(token.value for token in match.tokens[2:-1]) # 'Ололо!Еда'
import spacy
nlp = spacy.load('en')
doc = nlp(text)
str(doc[2:-1]) # 'Ололо! Еда'
Сравните простоту кода получения части исходной строки и то, что в Spacy пробелы на месте, а в Наташе - нет. Предлагаю в Наташе сделать так же.
PS: сейчас из-за деструктивной токенизации Наташи приходится выделять из строки весь Match
целиком и допиливать regexp-ом. Это не круто!
В вашем примере вы используете join по содержимому токенов - это не совсем то, что вам нужно, учитывая то, что внутри токенов хранится их оригинальное положение в тексте.
Не вижу проблем использовать original_text[span_start:span_end]
, в вашем случае, если нужна недеструктивная токенизация.
Собственно, про этот же способ чуть выше написал @alexanderkuk
Не нашёл, как иначе выдрать строку из
Match
. Пользуюсь пока вот так:Разрешаю скопировать код
to_slice
в библиотеку :)