Замораживание в регулярном выражении Python [дубликат]

Другим вариантом, если производительность является проблемой, является использование расширения data.table для расширения reshape2 расплава & amp; dcast functions

( Ссылка: эффективная перестройка с использованием data.tables )

library(data.table)

setDT(dat1)
dcast(dat1, name ~ numbers, value.var = "value")

#          name          1          2         3         4
# 1:  firstName  0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684  0.4874291 0.7383247 0.5757814

И, как и в data.table v1.9.6, мы можем использовать несколько столбцов

## add an extra column
dat1[, value2 := value * 2]

## cast multiple value columns
dcast(dat1, name ~ numbers, value.var = c("value", "value2"))

#          name    value_1    value_2   value_3   value_4   value2_1   value2_2 value2_3  value2_4
# 1:  firstName  0.1836433 -0.8356286 1.5952808 0.3295078  0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684  0.4874291 0.7383247 0.5757814 -1.6409368  0.9748581 1.476649 1.1515627

2
задан Alan Moore 11 September 2011 в 16:43
поделиться

3 ответа

Я должен признать, что это тоже меня удивило, но я получаю тот же результат в RegexBuddy: он прекращает попытки после миллиона шагов. Я знаю, что предупреждения о катастрофическом обратном трафике, как правило, сосредоточены на вложенных квантификаторах, но, по моему опыту, чередование, по крайней мере, опасно. На самом деле, если я изменю последнюю часть вашего регулярного выражения на это:

'(?:[^']+|'')+'

... к этому:

'(?:[^']*(?:''[^']*)*)'

... он терпит неудачу только одиннадцать шагов , Это пример метода Friedl «развернутого цикла», который он разбивает следующим образом:

opening normal * ( special normal * ) * closing
   '     [^']        ''     [^']           '

Вложенные звезды безопасны, если:

  1. special и normal никогда не могут совпадать с одним и тем же,
  2. special всегда совпадает хотя бы с одним символом, а
  3. special атомный (для него должен быть только один способ).

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

6
ответ дан Alan Moore 21 August 2018 в 19:38
поделиться
  • 1
    A миллион шагов , Алан? О, мой. Это на два порядка хуже, чем я получил в своем ответе. Интересно, что там происходит; идеи? Я предполагаю, что это показывает, почему вы можете доверять только результатам, с которыми вы работаете. – tchrist 11 September 2011 в 17:40
  • 2
    Не будет ли использование притяжательных кванторов или атомной группы еще лучше, и не будет еще быстрее? – Qtax 11 September 2011 в 17:45
  • 3
    RegexBuddy щедро выделяет свои «шаги», я заметил. Например, как [^']+, так и (?:[^']+|'')+ зачисляются отдельно для того, чтобы сжигать все после начального ', а затем есть три так называемого «обратного пути». перед тем, как он сделает что-нибудь, I будет вызывать обратное отслеживание. – Alan Moore 11 September 2011 в 18:10
  • 4
    @Qtax: Вы имеете в виду, в дополнение к развернутой петле? Это может провалиться на один или два шага быстрее, вот и все. Кстати, я не говорю, что вы должны использовать этот метод, когда доступны притяжательные кванторы и / или атомные группы. Но понимание почему это работает, всегда будет стоять на хорошем месте. – Alan Moore 11 September 2011 в 18:22
  • 5
    Боже мой. Версия Java действительно занимает примерно 100 раз больше, чем идентичная версия Perl. Версия Perl завершается, но медленно. Версия Java, похоже, висит, поэтому она страдает гораздо хуже. Понятия не имею почему. Мы никогда не узнаем, потому что мы не можем его профилировать. Увы. – tchrist 11 September 2011 в 20:48

Может кто-нибудь объяснить, почему механизм regex java переходит в катастрофический режим этого регулярного выражения?

Для строки:

'pão de açúcar itaucard mastercard platinum SUSTENTABILIDADE])

Кажется, что это часть регулярного выражения была бы проблемой:

'(?:[^']+|'')+'

Соответствие первой ', а затем неспособность совместить закрытие ' и, таким образом, отмена всех комбинаций вложенных кванторов.

Если вы разрешаете регулярному выражению возвращаться, он будет отступать (при сбое). Используйте атомарные группы и / или притяжательные квантификаторы, чтобы предотвратить это.


Btw, вам не нужна большая часть экранов в этом регулярном выражении. Единственное, что вам (возможно) нужно избегать в классах символов ([]) - это символы ^-]. Но обычно вы можете позиционировать их так, чтобы им тоже не нужно было бежать. Конечно, \ и все, что вы хотите, quoation, строка должна быть (двойной) экранирована.

"^(?:[^]['\"\\s~:/@#|^&(){}\\\\][^][\"\s~:/@#|^&(){}\\\\]*|\"(?:[^\"]++|\"\")++\"|'(?:[^']++|'')++')"
0
ответ дан Qtax 21 August 2018 в 19:38
поделиться
  • 1
    Qtax: Конечно, они это делают. – tchrist 11 September 2011 в 15:35
  • 2
    tchrist, редактирование разъясняет, что я имел в виду. – Qtax 11 September 2011 в 16:32
  • 3
    На самом деле вам все равно нужно избегать обратной косой черты, так что вы должны иметь двух из них не только одного. И ^ нужно только экранировать, если это первый символ, а - требуется только экранирование, если оно не является терминалом (первым или последним). Но это не имеет значения: я до сих пор считаю эту картину совершенно нечитаемой и недостижимой. Это действительно попадает под мою кожу, когда люди пишут такие вещи. Я знаю, что вы просто подражаете оригиналу, но оригинал заслуживает упрека, а не подражания. – tchrist 11 September 2011 в 17:48
15
ответ дан tchrist 21 August 2018 в 19:38
поделиться
Другие вопросы по тегам:

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