re.findall () не возвращает все триграммы / ngrams в предложении в Python [duplicate]

Кто-то знает, почему?

Да, потому что это то, что говорит спецификация языка. Трансляция выражения запроса содержится в разделе 7.16.2 спецификации C # 5.

В разделе 7.16.2.5 объясняется, почему ваш исходный пример неверен - Select не будет вызываться:

Выражение запроса формы

from x in e select v

переведен в

( e ) . Select ( x => v )

, за исключением случаев, когда v является идентификатором x, перевод просто

( e )

Например

from c in customers.Where(c => c.City == “London”)
select c

просто переведен на

customers.Where(c => c.City == “London”)

Однако это не относится к выражениям вырожденного запроса , которые охвачены в 7.16.2.3 - в котором объясняется, что происходит, когда вы удаляете предложение where:

Выражение запроса формы

from x in e select x

переведено на

( e ) . Select ( x => x )

Пример

from c in customers
select c

переведен в

customers.Select(c => c)

Выражение выраженного выражения - это то, которое тривиально выбирает элементы источника. Более поздняя фаза перевода удаляет вырожденные запросы, введенные другими шагами перевода, заменяя их их источником. Однако важно убедиться, что результат выражения запроса никогда не является исходным объектом, так как это выявит тип и идентификатор источника для клиента запроса. Поэтому этот шаг защищает вырожденные запросы, написанные непосредственно в исходном коде, путем явного вызова Select на источнике. Именно тогда разработчикам Select и другим операторам запросов следует гарантировать, что эти методы никогда не вернут исходный объект.

43
задан KL-7 11 July 2012 в 11:49
поделиться

3 ответа

findall не дает совпадающих совпадений по умолчанию. Однако это выражение:

>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']

Здесь (?=...) - это утверждение lookahead :

(?=...) соответствует, если ... соответствует затем, но не потребляет ни одной из строк. Это называется ожидаемым утверждением. Например, Isaac (?=Asimov) будет соответствовать 'Isaac ', только если за ним следует 'Asimov'.

72
ответ дан notpeter 21 August 2018 в 03:40
поделиться

Вы можете использовать новый модуль регулярного выражения Python , который поддерживает совпадающие совпадения.

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
23
ответ дан David C 21 August 2018 в 03:40
поделиться

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

Существует несколько утверждений с нулевой длиной (например, ^ (начало ввода / строки), $ (конец ввода / строка), \b (граница слова)), но look-arounds ((?<=) позитивный внешний вид и (?=) позитивный прогноз вперед ) - это единственный способ захватить перекрывающий текст из ввода. Отрицательные взгляды ((?<!) негативный внешний вид, (?!) негативный взгляд вперед] здесь не очень полезны: если они утверждают, что истина, то захват внутри потерпел неудачу; если они утверждают false, то совпадение не выполняется. Эти утверждения являются нулевой длиной (как упоминалось ранее), что означает, что они будут утверждать, не потребляя символы во входной строке. Они будут фактически соответствовать пустой строке, если утверждение прошло.

Применяя указанное выше знание, регулярное выражение, которое работает для вашего случая, будет:

(?=(\w\w))
7
ответ дан nhahtdh 21 August 2018 в 03:40
поделиться
Другие вопросы по тегам:

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