RegEx - значение & ldquo; not or & rdquo; правило [дубликат]

Полный рабочий код

import pandas as pd
df = pd.DataFrame(
    [['A', 'X', 3], ['A', 'X', 5], ['A', 'Y', 7], ['A', 'Y', 1],
     ['B', 'X', 3], ['B', 'X', 1], ['B', 'X', 3], ['B', 'Y', 1],
     ['C', 'X', 7], ['C', 'Y', 4], ['C', 'Y', 1], ['C', 'Y', 6]],
    columns=['c1', 'c2', 'v1'])

df['seq'] = df.groupby(['c1', 'c2']).cumcount() + 1
print(df)

Выход

   c1 c2  v1  seq
0   A  X   3    1
1   A  X   5    2
2   A  Y   7    1
3   A  Y   1    2
4   B  X   3    1
5   B  X   1    2
6   B  X   3    3
7   B  Y   1    1
8   C  X   7    1
9   C  Y   4    1
10  C  Y   1    2
11  C  Y   6    3
13
задан jrahhali 17 June 2015 в 19:34
поделиться

3 ответа

Поскольку Google возвращает этот SO-запрос поверх результатов для tempered greedy token, я чувствую себя обязанным предоставить более полный ответ.

Что такое закаленный жадный токен?

Ссылка rexegg.com tempered greedy token довольно кратка:

В (?:(?!{END}).)* квантор * применяется к точке, но теперь это закаленная точка. Отрицательный lookhhead (?!{END}) утверждает, что то, что следует за текущей позицией, не является строкой {END}. Поэтому точка никогда не сможет сопоставить открывающую фигуру {END}, гарантируя, что мы не будем перепрыгивать через разделитель {END}.

То есть: умеренный жадный token является своего рода отрицательным символьным классом для последовательности символа (см. отрицательный класс символов для single характер ).

ПРИМЕЧАНИЕ. Разница между умеренным жадным токеном и классом отрицательных символов заключается в том, что первый не соответствует тексту, отличному от самой последовательности, но single character , который не запускает эту последовательность. То есть (?:(?!abc|xyz).)+ не будет соответствовать def в defabc, но будет соответствовать def и bc, поскольку a запускает запрещенный abc и bc этого не делает.

Он состоит из:

  • (?:...)* - количественная группа, не захватывающая захват (это может быть группа захвата, но она не имеет смысла захватывать каждый отдельный символ) (* может быть +, это зависит от того, будет ли ожидаться пустая строка)
  • (?!...) - отрицательный результат, который фактически налагает ограничение на значение справа от текущего местоположения
  • . - (или любой (обычно одиночный) символ) шаблон потребления.

Однако мы всегда можем дополнительно умерить токен, используя чередование в негативном представлении (например, (?!{(?:END|START|MID)})) или заменяя точку совпадения символом с отрицательным символьным классом (например, (?:(?!START|END|MID)[^<>]) при попытке сопоставить текст только внутри тегов).

Распределение расходной части

Обратите внимание, что не упоминается конструкция, в которой потребляющая часть (точка в ориге inal tempered greedy token) помещается до . Ответ Авинаша ясно объясняет эту часть: (.(?!</table>))* сначала сопоставляет любой символ (но новую строку без модификатора DOTALL), а затем проверяет, не следует ли ему </table>, что приводит к сбою e в <table>table</table> .

Когда использовать умеренный жадный токен?

Rexegg.com дает идею:

  • Если мы хотим сопоставить блок текста между разделителем 1 и разделителем 2 без промежуточной подстроки 3 (например, {START}(?:(?!{(?:MID|RESTART)}).)*?{END}
  • Если мы хотим сопоставить блок текста, содержащий специфический шаблон внутри без переполнения последующих блоков (например, вместо ленивого совпадения точек, как в <table>.*?chair.*?</table> , мы будем использовать что-то вроде <table>(?:(?!chair|</?table>).)*chair(?:(?!<table>).)*</table> ).
  • Когда мы хотим совместить кратчайшее возможное окно между двумя строками. Лестное совпадение не поможет, когда вам нужно получить abc 2 xyz из abc 1 abc 2 xyz (см. abc.*?xyz и abc(?:(?!abc).)*?xyz ).

Проблема с производительностью

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

Скажем, мы хотим сопоставить abc 2 xyz в abc 1 abc 2 xyz 3 xyz . Вместо проверки каждого символа между abc и xyz с помощью abc(?:(?!abc|xyz).)*xyz мы можем пропустить все символы, которые не являются a или x, с [^ax]*, а затем соответствуют всем a, за которыми не следуют bca(?!bc)) и все x, за которыми не следует yzx(?!yz)): abc[^ax]*(?:a(?!bc)[^ax]*|x(?!yz)[^ax]*)*xyz .

34
ответ дан Wiktor Stribiżew 23 August 2018 в 20:42
поделиться

((?!</table>).)* будет проверять, что этот конкретный символ, который будет согласован, не должен быть начальным символом в строке </table>. Если да, то только он соответствует этому конкретному символу. * повторяет то же самое ноль или более раз.

(.(?!</table>))* соответствует любому символу, только если за ним не следует </table>, ноль или более раз. Таким образом, это будет соответствовать всем символам внутри тега таблицы excpet последнего символа, так как за последним символом следует </table>. И следующий шаблон </table> утверждает, что в конце матча должен быть тег закрывающей таблицы. Это приводит к сбою совпадения.

См. здесь

9
ответ дан Avinash Raj 23 August 2018 в 20:42
поделиться

умеренный токен действительно просто означает:

"соответствует, но только до точки"

, как вы делаете это:

вы помещаете токен , который вы не хотите сопоставлять как отрицательный lookahead (?!notAllowedToMatch) перед точкой . (соответствует любому одна вещь), то вы повторяете , что вся вещь со звездой *:

((?!notAllowedToMatch).)*

как это работает:

«смотреть и есть один» снова и снова, перемещая по одному символу слева направо через входную строку до тех пор, пока запрещенная последовательность (или конец строки ), в этот момент матч останавливается.

Более подробный ответ Wiktor - это хорошо, я просто подумал, что более простое объяснение было в порядке.

3
ответ дан sweaver2112 23 August 2018 в 20:42
поделиться
Другие вопросы по тегам:

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