My favorite regex of all time
catonmat.net
catonmat.net
[ -~] #match only printable characters
It takes 5 seconds longer and with regexes, just knowing what the damn thing is trying to do is half the battle. When you use a regex, use a comment. Its the civil thing to do.
I do agree that it might be overkill to move regexes to their own functions just for readability's sake but I don't buy the performance argument. Furthermore, regexes are most popular in scripting languages that no sane person would use for real time performance-critical systems anyway.
2. Web sites are a classic example of scripting languages being used for real time performance critical systems (though I'm not arguing that all web sites are real time).
Sometimes the ability to modify code easily is as important to the choice of languages as the raw execution speed of the compiled binaries.
If you're using a regex, and certainly if you're using a language other than C, you probably have space for the function call overhead.
Sometimes C is inappropriate (eg you'd be nuts to build a website in C yet some sites do offer real time services)
Often the data set and/or logic required makes C an inappropriate language (eg you wouldn't use C for AI nor for some types of database operations).
And even in the cases where you're just building a standard procedural system, sometimes the interface lends itself better to other languages (eg C would be possibly the worst language for real time websites.)
But even in the cases where you're building a solution that's suited for C, there are still other performance languages which could be used.
"Real time" is quite a general term and as such, sometimes it makes more sense to use scripting languages which are performance tuned. Which is where writing 'good' PCRE is critical as RegEx can be optimised and compiled - if you understand the quirks of the language well enough to avoid easy pitfalls, eg s/^\s//; s/\s$//; outperforms s/(^\s|\s$)//; despite it being two separate queries as opposed to one.
If you're in a situation where the overhead of a couple of function calls is unacceptable, regexes are totally unacceptable and you need to write custom character manipulation.
This situation is really rare and in almost all business cases, using C is inappropriate.
It is the selfish (but smart) thing to do.
The worst case is when the original author never really had it clear in his/her mind what exactly that compound regex was trying to accomplish. They just kind of bodged and hacked till the usual input stream started coming out right. Trying to write a clear comment on the purpose of the regex helps with that too.
Makes sorts really tweaky.
So I read the snippet, thought 'Yeah, a character class of space, -, ~' and fell on my face in the next couple of lines.
Yeah, I should've known better, I know how to read it. If .. I invest the time and don't glance over a construct and hope to just get it instantly.
I wouldn't want to see this in a code base without proper documentation (be it a comment, a function name or whatever. Something).
http://searchco.de/?q=%5B+-~%5D+ext%3Apod&cs=on http://symbolhound.com/?q=%5B+-~%5D
Symbolhound gives the answer quite well, and searchco.de has some examples of its use in the results.
That one author is the only person who knows what s/he is trying to achieve.
That author taking a few minutes to add some comments will save other people the time to search for answers and the time it takes to grok everything.
Even if I can figure out what the regex matches (with Google or something else), that doesn't necessarily tell me WHY I'm matching on that particular pattern, or why I needed a RegEx in this spot, or what the intent was at the time of writing it.
/x allows you to break up your regex into its component parts, one part per line, and then comment each part.
Here is what the manual says about /x:
/x tells the regular expression parser to ignore most whitespace that is neither backslashed nor within a character class. You can use this to break up your regular expression into (slightly) more readable parts. The # character is also treated as a metacharacter introducing a comment, just as in ordinary Perl code. This also means that if you want real whitespace or # characters in the pattern (outside a character class, where they are unaffected by /x), then you'll either have to escape them (using backslashes or \Q...\E ) or encode them using octal, hex, or \N{} escapes. Taken together, these features go a long way towards making Perl's regular expressions more readable.
You are right anyway.
[[:print:]]
to use the explicit character class.I used this once as another safeguard against pushing binary data into the database. It was a poor system to begin with where you even have that possibility... and it happened at least once before the fix and my safeguard was in place.
Email could be an example, I guess, although I haven't worked with it enough to know whether the whole "7-bits only" thing is still an issue these days.
/^1?$|^(11+?)\1+$/
Which finds prime numbers. Although, I can't for the life of me think of a reason for using it.
http://stackoverflow.com/questions/3296050/how-does-this-reg...
The first part (^1?$) allows "" and "1" to match (so that 1 is not detected as a prime).
The second part matches groups of two or more ones (11+?), repeated twice or more, ie products n*m, n ≥ 2, m ≥ 2.
The backreference means that \1 should match the exact same string as the first (11+?). It's different from using (11+?){2,} which would match n_1+n_2+n_3..., n_1 ≥ 2, n_2 ≥ 2, n_3 ≥ 2 (where submatch is independent).
http://news.ycombinator.com/item?id=1486502
full comment thread here http://news.ycombinator.com/item?id=1486158
I suppose I could accept "regex" as not being a regular expression as such, but the two are used so interchangeably that maintaining a distinction isn't very realistic. I'd personally rather a regular expression described a regular language, and "PCRE" (or so) used for the Turing-complete expressions with a similar syntax.
So I'd argue that code is RegEx.
I guess it's just a matter of perspective though.
Many filesystems don't support unicode or support only a subset of it:
https://en.wikipedia.org/wiki/Filename#Comparison_of_filenam...
> Also domains and URLs can be unicode too.
Domains: it depends at which level you are dealing with them. See https://en.wikipedia.org/wiki/Internationalized_domain_name
Internationalized domain names are stored in the Domain
Name System as ASCII strings using Punycode transcription.
URLs: Unicode characters are not allowed in URLs. See http://www.faqs.org/rfcs/rfc1738.html and http://www.blooberry.com/indexdot/html/topics/urlencoding.ht... only alphanumerics, the special characters "$-_.+!*'(),", and
reserved characters used for their reserved purposes may be used
unencoded within a URL.For example, a few years ago I grabbed a source tarball from somewhere, I forget what or where. It had the author's name in a comment, which included an O with dots over it. That was the only non-ASCII character in the source code. No matter what I did, both Eclipse and command-line javac refused to compile the source.
Finally I wrote a script to delete his name from every source file manually. It compiled flawlessly.
Then there's the time I found some text files with two characters of binary junk at the beginning, followed by completely normal text. Again, I forget what I was doing, but some program was refusing to process them correctly. It was something internationalization-related called the BOM. Eventually I ended up writing a script to walk a directory and remove the first two bytes of every file. (This can probably be done with dd and xargs on UNIX, but I was using Windows at the time, which means that something like this will require spending an hour or so in your favorite programming language.)
These experiences lead me to believe that, for bootstrapped USA startups at least, you shouldn't worry about a market outside the English-speaking world.
If you need to worry about junk like accented characters or moon runes (Chinese/Japanese/Korean characters), it means you're big enough to afford to hire someone specifically to address the problem.
How do you define "English-speaking world", btw? Those too ignorant to have heard of non-ascii-characters (ie: excluding Canada, as anyone doing business there should at least have heard of French)?
Anyway, for anyone actually burnt by something similar on a GNU system try looking up recode(1).
http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark
And personally I think to exclude all internationalisations because they're harder is a terrible attitude to have. Particularly these days when there's an online tutorials for pretty much any job imaginable (not to mention the numbers of helpful experts willing to give up their time for free on various forums and communities).
Ok, this is where I stop worrying about how quickly I write code. Did this (removing BOM) quite a few times and it took just a few minutes in Python (under Windows). Heck, this could be two-liner I think :)
EDIT: It works fine for comments, at least.
What else could this have been besides match the character range from space to tilde?
I don't think it is particularly bad though. It's just not the most trivial of regexes.
I know there's some syntax I can use to create a zero width negative look behind recursive greedy named capture group back reference. Perhaps hyphen-tilde triggers something like that.
Because enough people voted it up within a set time window.
We definitely aren't the only ones who appreciate horrible things.
INTERCAL comes to mind here.
[^ -~]
Not to be used in a serious program, but only in an editor (or maybe one-shot data massage perl scripts), to find possible errors or unexpected stuff.
See my comments [1] [2] [3] for why Unicode / internationalization should be avoided.
[1] http://news.ycombinator.com/item?id=4369323
Even if you focus on u.s., you will have problems. If you're doing a CRM, even u.s. users will put in foreign names from time to time. If you're building a CMS, users may want to put in a quotation in french, or will simply use copy&paste from Word, which replaces "-" with "—"...
I honestly have a hard time finding a u.s. centric startup which could afford to ignore unicode. The support requests, the fires caused by errors, and the disclaimer that you'd have to put on the registration page, would cost much more than simply learning how to code the f'n utf.
Building MVP is good practice in Lean. Saying "I'm bootstrapping hence I don't have the time to learn the programming tools" is just ignorance and incompetence. It's not like Unicode gives you extra work, it just requires you to learn a few basic concepts. If you try to build a site which doesn't support Unicode, you'll have to put a lots of safeguards everywhere to cover up for your incompetence.
/[^ -~] > \p{L} or \p{Letter}: any kind of letter from any language.
vs > \p{L&} or \p{Letter&}: a letter that exists in lowercase and uppercase variants (combination of Ll, Lu and Lt).
Along with: > \p{Z} or \p{Separator}: any kind of whitespace or invisible separator.
Considering the op matches everything printable, including whitespace (or actually just space, not tab), numbers and punctation, I think the equivalent would be "\X" ?All this based on glancing at:
http://www.regular-expressions.info/unicode.htmlThe bracket expression [ ] defines single characters to match, however you can have more then 1 character inside which all will match.
[a] matches a
[ab] matches either a or b
[abc] matches either a or b or c
[a-c] matches either a or b or c.
The - allows us to define the range. You can just as easily use [abc] but for long sequences such as [a-z] consider it short hand.In this case [ -~] it means every character between <space> and <tilde>, which just happens to be all the ASCII printable characters (see chart in the article). The only bit you need to keep in mind is that <space> is a character as well, and hence you can match on it.
You could rewrite the regex like so (note I haven't escaped or anything in this so its probably not valid)
[ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~]
but that's not quite as clever or neat.