В чем причина того, что подстроки в регулярном выражении должны быть упорядочены по длине?

самый длинный

>>> p = re.compile('supermanutd|supermanu|superman|superm|super') 

самый короткий сначала

 >>> p = re.compile('super|superm|superman|supermanu|supermanutd') 

Почему самое длинное первое регулярное выражение предпочтительнее?

Альтернативы в регулярных выражениях проверяются для того, чтобы вы предоставили, поэтому, если первая ветвь соответствует, тогда Rx не проверяет другие ветви. Это не имеет значения, если вам нужно только проверить соответствие, но если вы хотите извлечь текст на основе соответствия, это имеет значение.

Вам нужно сортировать по длине, когда ваши короткие строки являются подстроками более длинных. Например, когда у вас есть текст:

 supermanutd supermanu superman superm 

то с вашим первым Rx вы получите:

 >>> regex.findall(string) [u'supermanutd', u'supermanu', u'superman', u'superm'] 

но со вторым Rx:

 >>> regex.findall(string) [u'super', u'super', u'super', u'super', u'super'] 

Проверьте свои регулярные выражения с помощью http://www.pythonregex.com/

Как говорит @MBO, альтернативы тестируются в том порядке, в котором они написаны, и как только один из них соответствует, двигатель RE продолжает работу.
Такое поведение характерно для движков RE, подобных Perl, и в конечном итоге восходит к дизайну Bell Labs 1985 года в библиотеке RE для Unix версии 8.
Обратите внимание, что POSIX 2 (с 1991 года) имеет другое определение, настаивая на самом левом самом длинном совпадении для всего RE и подчиняется этому, для каждого подвыражения в свою очередь (в лексическом порядке). В POSIX 2 порядок альтернатив не имеет значения.

Тем не менее, разница в поведении часто: неактуальна (если вы просто проверяете), замаскированная путем обратного отслеживания (если более короткое совпадение приводит к сбою остальной части RE) или компенсируется остальной частью RE, соответствующей части, более длинный матч «должен иметь» – поэтому большинство людей не знают об этом.

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

Но на практике вы должны измерять, а не догадываться. Если вам нужно иметь регулярное выражение для выполнения, проверьте варианты тестирования на репрезентативные тестовые данные.

Совет, на который вы ссылаетесь, зависит от механизма регулярных выражений, который пытается сопоставить компоненты чередования в строго упорядоченном порядке слева направо, как это описано в модуле Python re.

Сортировка подстрок в порядке убывания длины – это особый случай более широкой проблемы, когда вы пытаетесь извлечь серию жетонов. Общий принцип заключается в том, что вы сначала ставите более специализированные подрегремы. Например, вы пишете лексический анализ для парсера формулы. У вас есть подпороговая константа «float constant» и подстрока «int constant». Ваша первая попытка подповерхности с плавающей точкой, вероятно, также будет соответствовать int-константам. Если это так, у вас есть два варианта: (1) напишите более сложный подпорок float, который не соответствует int constants (2) сначала помещает ваш int subregex.