Я использую Python regexes преступно неэффективным способом

Используйте

import pandas as pd
current_date = pd.Timestamp('Jan 20, 2019')
while True:
    if 15 <= current_date.day <= 21 and current_date.day_name() == 'Thursday':
        break
    current_date +=pd.DateOffset(1)

print(current_date)

#2019-02-21 00:00:00
7
задан Andy Lester 7 October 2008 в 00:38
поделиться

10 ответов

Первая вещь, которая может улучшить вещи, состоит в том, чтобы переместить re.compile вне функции. Компиляция кэшируется, но существует скорость, пораженная в проверке этого, чтобы видеть если его скомпилированный.

Другая возможность состоит в том, чтобы использовать единственный regex как указано ниже:

MatchedQuotes = re.compile(r"(['\"])(.*)\1", re.LOCALE)
item = MatchedQuotes.sub(r'\2', item, 1)

Наконец, можно объединить это в regex в processVariables. Беря предложение Torsten Marek для использования функции для re.sub это улучшает и упрощает вещи существенно.

VariableDefinition = re.compile(r'<%(["\']?)(.*?)\1=(["\']?)(.*?)\3%>', re.LOCALE)
VarRepl = re.compile(r'<%(["\']?)(.*?)\1%>', re.LOCALE)

def processVariables(item):
    vars = {}
    def findVars(m):
        vars[m.group(2).upper()] = m.group(4)
        return ""

    item = VariableDefinition.sub(findVars, item)
    return VarRepl.sub(lambda m: vars[m.group(2).upper()], item)

print processVariables('<%"TITLE"="This Is A Test Variable"%>The Web <%"TITLE"%>')

Вот мои синхронизации для 100 000 выполнений:

Original       : 13.637
Global regexes : 12.771
Single regex   :  9.095
Final version  :  1.846

[Редактирование] Добавляет недостающий нежадный спецификатор

[Edit2] Добавленный .upper () называет таким образом нечувствительным к регистру как исходная версия

10
ответ дан 6 December 2019 в 10:55
поделиться

sub может взять вызываемое, поскольку это - аргумент, а не простая строка. Используя это, можно заменить все переменные одним вызовом функции:

>>> import re
>>> var_matcher = re.compile(r'<%(.*?)%>', re.LOCALE)
>>> string = '<%"TITLE"%> <%"SHMITLE"%>'
>>> values = {'"TITLE"': "I am a title.", '"SHMITLE"': "And I am a shmitle."}
>>> var_matcher.sub(lambda m: vars[m.group(1)], string)
'I am a title. And I am a shmitle.

Последуйте совету eduffy.myopenid.com и сохраните скомпилированный regexes вокруг.

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

3
ответ дан 6 December 2019 в 10:55
поделиться

Никогда не создавайте свой собственный язык программирования. Когда-либо. (Я раньше имел исключение к этому правилу, но не больше.)

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

2
ответ дан 6 December 2019 в 10:55
поделиться

Создание языка шаблонной обработки является всем хорошо и хороший, но не был должен одна из целей языка шаблонной обработки быть легкой удобочитаемостью и эффективным парсингом? Пример, который Вы дали, кажется, не ни один.

Поскольку Jamie Zawinsky заметно сказал:

Некоторые люди, сталкиваясь с проблемой, думают, что "Я знаю, я буду использовать регулярные выражения!" Теперь у них есть две проблемы.

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

2
ответ дан 6 December 2019 в 10:55
поделиться

Можно соответствовать обоим видам кавычек сразу с r"(\"|')(.*?)\1" - \1 относится к первой группе, таким образом, она будет только соответствовать соответствию кавычкам.

1
ответ дан 6 December 2019 в 10:55
поделиться

Вы называете re.compile вполне немного. Глобальная переменная для них не причинила бы боль здесь.

1
ответ дан 6 December 2019 в 10:55
поделиться

Если regexp только содержит один.* подстановочный знак и литералы, то можно использовать, находят и rfind для определения местоположения открытия и заключительных разделителей.

Если это содержит только серию.*? подстановочные знаки и литералы, затем можно просто использовать серию находки, чтобы сделать работу.

Если код строго ограничен во времени, этот переключатель далеко от regexp's в целом мог бы дать немного больше скорости.

Кроме того, это смотрит на меня как это, язык LL-parsable. Вы могли искать библиотеку, которая может уже проанализировать такие вещи для Вас. Вы могли также использовать рекурсивные вызовы, чтобы сделать синтаксический анализ с одной передачей - например, Вы могли реализовать свою функцию processVariables, чтобы только использовать первую кавычку и затем вызвать соответствующую кавычке функцию для потребления до следующей кавычки, и т.д.

1
ответ дан 6 December 2019 в 10:55
поделиться

Почему бы не использовать Мако? Серьезно. Какая функция Вы требуете, чтобы Мако не имел? Возможно, можно адаптировать или расширить что-то, что уже работает.

1
ответ дан 6 December 2019 в 10:55
поделиться

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

0
ответ дан 6 December 2019 в 10:55
поделиться

Почему бы не использовать XML и XSLT вместо того, чтобы создать Ваш собственный шаблонный язык? То, что Вы хотите сделать, довольно легко в XSLT.

-3
ответ дан 6 December 2019 в 10:55
поделиться
Другие вопросы по тегам:

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