Соответствие строки TCL и регулярные выражения - PullRequest
5 голосов
/ 14 сентября 2011

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

Ответы [ 6 ]

4 голосов
/ 14 сентября 2011

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

Если вы просто ищете фиксированную последовательность символов, используйте строковые операции.

Если вы ищетедля шаблона используйте регулярные выражения.

Пример

Найдите слово «Foo».использовать строковые операции, он также найдет "Foobar", это нормально?НЕТ, тогда, может быть, будет поиск «Foo», но тогда он не найдет «Foo» и «Foo».

С регулярным выражением проблем нет, вы можете сопоставить границу слова / \ mFoo \ M /и это регулярное выражение не будет медленным.

Я думаю, что это негативное изображение возникает из-за особых проблем, таких как катастрофический откат .

Был недавний пример ( катастрофическое обратное отслеживание, которое не должно происходить на этом регулярном выражении ), где это поведение было неожиданным.

Заключение

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

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

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

Вот интересное прочтение об оптимизации кода

3 голосов
/ 14 сентября 2011

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

string match - или globbing - можетследует рассматривать как упрощенную версию регулярных выражений.Шаблон glob обычно будет короче, чем эквивалентное регулярное выражение (классы символов являются исключением - ER поддерживают их, а с globs вам нужно их прописать).Я не знаю, как отличается производительность;Я бы ожидал, что string match будет немного быстрее на эквивалентных шаблонах из-за более простой логики, но time гораздо надежнее ожиданий.

В конкретном случае, когда RE легче использовать, извлечениеПодстрока контекстуально против простой позиции символа является хорошим примером.Или для сопоставления одной из нескольких альтернатив.

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

2 голосов
/ 14 сентября 2011

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

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

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

1 голос
/ 15 сентября 2011

Соответствие регулярному выражению является разновидностью строковой операции. Хотя он не такой быстрый, как некоторые из более простых операций, он также чрезвычайно эффективен. Его также сложнее использовать, особенно если вы еще не знаете базовый синтаксис RE, но это не повод избегать их. Однако замена регулярного выражения набором базовых строковых операций может привести к значительному увеличению длины программы: иногда вам просто необходимы сложные манипуляции.

Tcl делает несколько вещей, чтобы сделать операции RE более эффективными. Примечательно, что он обнаруживает особенно простые RE и преобразует их в глобальные совпадения (как в string match), которые являются более быстрыми, но гораздо менее мощными, и выполняет ряд операций, чтобы кэшировать скомпилированную форму RE, чтобы сопоставление было меньше накладных , Он также использует теоретико-автоматный механизм сопоставления, который имеет меньше сюрпризов во время сопоставления (и требует больше времени для компиляции RE в первую очередь).

Короче, не избегайте их. Используйте их там, где это необходимо. (И time, если вы сомневаетесь в скорости.)

1 голос
/ 14 сентября 2011

Я не знаю, в частности, о Tcl, но в целом можно сказать, что если вы ищете точные совпадения текста (например, найдите все строки, которые начинаются с #define), тогда строковые операции выполняются быстрее.Но если вы ищете шаблонов (например, все строки, которые содержат слово, начинающееся с c и заканчивающееся t), то регулярные выражения являются правильным инструментом для этого (\bc\w*t\b будетхорошее регулярное выражение для этого - сравните это с логикой программы, которая вам понадобится, если бы вам пришлось написать это самостоятельно.

И даже если регулярное выражение медленнее в таком случае, велики шансы, что оно не будетимеет значение с точки зрения скорости выполнения, но это будет иметь большое значение, когда требуются изменения в логике сопоставления (о, теперь нам нужно найти слово, которое начинается с c и заканчивается t, но содержит как минимум дваa s и нет x -> \bc(?=\w*a\w*a)(?!\w*x)\w*t\b).

Место, куда большинство движков регулярных выражений не хотят идти, это рекурсия (соответствующие вложенные теги, вложенные скобки и все такое).где парсеры вводят картинку.

0 голосов
/ 14 сентября 2011

regexp иначе регулярные выражения используются для сопоставления множества различных строк и могут быть очень сложными или даже для проверки конкретного ввода.
string match допускает только подстановочные знаки, такие как * и ? и группирование основных символов с [], как в регулярном выражении.
Вы можете прочитать об этом здесь: http://www.tcl.tk/man/tcl8.5/TclCmd/string.htm#M40
Базовое руководство, что может сделать regexp также с некоторыми примерами, объясняется здесь: http://www.regular -expressions.info /

Итак, вкратце: если вам не нужно регулярное выражение или даже вы не знаете о нем много, я рекомендую вам не использовать его. Если вы просто хотите сравнить две строки на предмет их равенства, используйте string equal.

...