开发者

TCL string match vs regexps

开发者 https://www.devze.com 2023-04-04 22:08 出处:网络
Is it开发者_高级运维 right that we should avoid using regexp as it is slow. Instead we should use string operations. Are there cases that both can be used but regexp is better?You should use the appro

Is it开发者_高级运维 right that we should avoid using regexp as it is slow. Instead we should use string operations. Are there cases that both can be used but regexp is better?


You should use the appropriate tool for the job. That means, you should not avoid regex, you should use it when it is necessary.

If you are just searching for a fixed sequence of characters, use string operations.

If you are searching for a pattern, then use regular expressions.

Example

Search for the word "Foo". use string operations it will also find "Foobar", is this OK? NO, well then maybe search for "Foo ", but then it will not find "Foo," and "Foo."

With regex no problem, you can match for a word boundary /\mFoo\M/ and this regex will not be slow.

I think this negative image comes from special problems like catastrophic backtracking.

There has been a recent example (catastrophic-backtracking-shouldnt-be-happening-on-this-regex) where this behaviour was unexpected.

Conclusion

A regex has to be well designed, if it isn't then the performance can be catastrophic. But the same can also happen to your normal code if you use a bad algorithm.

For a small job it should nearly never be a problem to use a regex, if your task is bigger and has to be repeated often, do a benchmark.

From my own experience, I am analyzing really big text files (some hundred MB) and use regexes to find the rows I am interested in and I don't experience performance problems because of regex.

Here an interesting read about code optimization


Regular expressions (REs) are a marvelous hammer. They can solve some problems elegantly, and many more with brute force, but it won't be pretty. And some problems can be solved with REs if you hit them enough, but there are much better solutions available (for example, things that are a good fit for string map)

string match - or globbing - can be thought of as a simplified version of regular expressions. The glob pattern will usually be shorter than the equivalent regular expression (character classes are an exception - ERs support them, with globs you need to spell them out). I don't know offhand how the performance differs; I'd expect string match to be slightly faster on equivalent patterns because of the simpler logic, but time is much more reliable than expectations.

For a specific case where REs are easier to use, extracting a substring contextually vs. by simple character position is a good example. Or for matching one of several alternatives.

My rule of thumb is to use the simplest thing that works. If that's string match, then great. If it seems like the pattern is too complex for that, go to a regexp and be happy you have the choice.


The best advice I can give, and the advice I use myself is, use regular expressions only when a simpler solution won't work.

If you can use simple string matching, or use glob patterns, use them. It's only when those cannot work that you should be using regular expressions.

To address your specific question I would say that, no, there is no time when you can use either but that regular expressions are the better choice. Maybe there's an edge case I'm not thinking of, but generally speaking, simpler solutions are always better.


I don't know about Tcl in particular, but generally it can be said that if you're looking for exact text matches (e. g. find all lines that start with #define) then string operations are faster. But if you're looking for patterns (e. g. all lines that contain a word that starts with c and ends with t) then regular expressions are the right tool for this (\bc\w*t\b would be a good regex for this - compare this to the program logic you'd need if you had to write this yourself.

And even if regex is slower in a case like this, chances are high that it won't matter in terms of execution speed, but it'll matter a lot when changes to the matching logic are required (oh, now we need to look for a word that starts with c and ends with t but contains at least two as and no x --> \bc(?=\w*a\w*a)(?!\w*x)\w*t\b).

A place where most regex engines don't want to go is recursion (matching nested tags, nested parentheses and all that). That's where parsers enter the picture.


Regular expression matching is a kind of string operation. While it's not as fast as some of the more basic operations, it is enormously more capable too. It's also more difficult to use, especially if you don't already know the basic syntax of REs, but that's not a reason to avoid them. However, replacing a regular expression with a collection of basic string operations can just lead to the program getting enormously longer: sometimes, you simply need complex manipulations.

Tcl does a number of things to make RE operations more efficient. Notably, it detects particularly simple REs and converts them into glob-like matches (as in string match) which are faster but much less powerful, and it does a number of things to cache the compiled form of REs so that matching has less overhead. It also uses an automata-theoretic matching engine that has fewer surprises during match time (at a cost of more time to compile the RE in the first place).

In short, don't avoid them. Use them where appropriate. (And time if you're in doubt about speed.)


regexp aka regular expressions are used to match many different strings and can be very complex or even to validate a specific input.
string match only allows wildcards such as * and ? and basic character grouping with [] as in regexp.
You can read about it here: http://www.tcl.tk/man/tcl8.5/TclCmd/string.htm#M40
A basic guide what regexp can do also with some examples are explained here: http://www.regular-expressions.info/

So in short: If you don't need regexp or even don't know much about it, i recommand you to not use it. If you just want to compare two strings for their equality use string equal.

0

精彩评论

暂无评论...
验证码 换一张
取 消