6 ms·
RegExpBuilder – Create regular expressions using chained methods
- chris-at 12y agoThanks, this is a lot better than writing this (even if the formatting worked here): ``` (?xi) \b ( # Capture 1: entire matched URL (?: [a-z][\w-]+: # URL protocol and colon (?: /{1,3} # 1-3 slashes | # or [a-z0-9%] # Single letter or digit or '%' # (Trying not to match e.g. "URI::Escape") ) | # or www\d{0,3}[.] # "www.", "www1.", "www2." … "www999." | # or [a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash ) (?: # One or more: [^\s()<>]+ # Run of non-space, non-()<> | # or \(([^\s()<>]+|(\([^\s()<>]+\)))\) # balanced parens, up to 2 levels )+ (?: # End with: \(([^\s()<>]+|(\([^\s()<>]+\)))\) # balanced parens, up to 2 levels | # or [^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars ) ) ```
- whichdan 12y agoHN doesn't support Markdown. You'll need to prefix each line with >= 2 spaces for it to be treated as code. https://news.ycombinator.com/formatdoc https://news.ycombinator.com/formatdoc
- UnoriginalGuy 12y agoThat really is Hacker News' worst limitation. I understand if they want to limit what formatting is available, but the fact that basic listing is so clunky is annoying.
- _lce0 12y agoactually most of the comments seem to imply that whoever wrote that don't fully understand regexp syntax -- or, worst, she expects that whoever read will not /{1,3} # 1-3 slashes | # or [a-z0-9%] # Single letter or digit or "%";
- GhotiFish 12y agoerr... sorry? https://www.debuggex.com/r/EpocMU_7Fq_B_p9z https://www.debuggex.com/r/EpocMU_7Fq_B_p9z edit: wait, I thought about it for a second and I see what you meant. You're not saying it's wrong, you're saying it's obvious. I wasn't sure if it was obvious because I wasn't sure if {1,3} was supposed to be {1-3} and there was a mistake in the expression, or if there was some kind of unexpected error in the [a-z0-9%] expression. Because even in this simple example, there is room for error.
- tlrobinson 12y agoProperly formatted (to be fair this is from a blog post explaining how the regex works: http://daringfireball.net/2010/07/improved_regex_for_matching_urls http://daringfireball.net/2010/07/improved_regex_for_matchin...): (?xi) \b ( # Capture 1: entire matched URL (?: [a-z][\w-]+: # URL protocol and colon (?: /{1,3} # 1-3 slashes | # or [a-z0-9%] # Single letter or digit or '%' # (Trying not to match e.g. "URI::Escape") ) | # or www\d{0,3}[.] # "www.", "www1.", "www2." … "www999." | # or [a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash ) (?: # One or more: [^\s()<>]+ # Run of non-space, non-()<> | # or \(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels )+ (?: # End with: \(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels | # or [^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars ) )
- raiph 12y agocf the Perl 6 community module for parsing URIs which features Perl 6's unique unification of regexes and grammars: https://github.com/perl6-community-modules/uri/blob/master/lib/IETF/RFC_Grammar/URI.pm https://github.com/perl6-community-modules/uri/blob/master/l...
- gcao 12y agoGreat work! This is very intriguing!
- tragomaskhalos 12y agoThere have been many efforts similar to this in many languages, but most of us seem happy to stick to the more succinct canonical form, supplemented via /x # comments when things get too hairy
- marktangotango 12y agoGenerally, I find that if one's regexes are so complex that one needs visualizers or other aids in writing them, one doesn't have a regex problem, but a parsing problem. The method of parsing by recursive descent can often lead to much more understandable (if more verbose) "pattern matching".
- DenisM 12y agoRecursive descend is imperative, while regex is declarative. Regex may be ugly, but you lose something important when you move from declarative to imperative.
- jerf 12y ago"Recursive descent" has that name precisely because it is not the only parsing alternative, hence we can not simply call it "parsing".
- raiph 12y agoPerl 6 unifies "regexes" and recursive descent. See https://news.ycombinator.com/item?id=9039680 https://news.ycombinator.com/item?id=9039680 or, say, https://github.com/Mouq/json5/blob/master/lib/JSON5/Tiny/Grammar.pm6 https://github.com/Mouq/json5/blob/master/lib/JSON5/Tiny/Gra...
- otakucode 12y agoThe worst regexes I've had to write involved parsing the various IMDB data files, which seem to have been formatted specifically to make them as difficult to parse as possible. I hear mediawiki syntax is similarly arcane and evil, but I've never tried to parse it (though last night I started writing some tools to deal with wikipedia dumps so I might end up in that corner). I'd really like to see different approaches to parsing really ugly formats that feature an exception to almost every single pattern you think you've found. I honestly think the regex is easiest...
- dkarapetyan 12y agoGeneralize just a little bit and you got parser combinators.
- UnoriginalGuy 12y agoLooks like Linq (from .Net/C#). Pretty sexy way to write Regular Expressions if you ask me. I've "learned" regular expressions multiple times but it just never sticks, I have no idea why. It certainly doesn't help that there are several different incompatible syntaxes (so what I remember and think "should" work doesn't). I'd prefer to write RegX's in this style, however I would pay attention to performance (not that Regular Expressions are high performance, however I wouldn't want to see a large performance loss either).
- UK-AL 12y agoRegular expressions are high performance if you use automata style(Regular Language) regular expressions, which limits the use of some of the features you can use. Modern regular expression engines in a lot of languages, actually go beyond the expressiveness of a regular language. This is what damages performance. There is no reason why this would reduce performance... if its not doing anything crazy. If anything your taking work away from it. Your building the tree directly here, where as parser would normally build a tree from the string. But since this is integrating into the languages RE library i'm guessing its writing that tree as a string, which is then passed into the regular expression engine, to be turned into a tree again :)
- UnoriginalGuy 12y agoI guess it depends on your definition of "high performance." If a regular expression runs too often, even pre-compiled (as they should be), you'll want to replace them with code written in the native language. I've gone in and replaced a one line search/replace written in RegX (compiled), with just a C-style for() loop over the wchar array, and had the memory usage drop by near 80% and performance increase by over 60%. So high performance is all relative. However RegX isn't something I'd describe that way, even compiled. It is a nice way to write complex string parsing code quickly however.
- UK-AL 12y agoA regular expression implemented as a DFA would literally be looping over the string, and a state transition table. I don't see how performance could be bad. It is highly dependent on the regular expression engine you use, most don't use automata because of extra features.
- jgalt212 12y agoDefinitely a debugable way to write regexes. Whenever I have to maintain a hairy regex, I like to plot the regex as a railroad diagram. These web based tools can do it: https://www.debuggex.com/ https://www.debuggex.com/ http://jex.im/regulex/ http://jex.im/regulex/
- philjohn 12y agoLove it - just visualised the PCRE generated from the EBNF for the N-Triples RDF serialisation format[1] :) https://www.debuggex.com/r/Yxqws81Uif-BGBN8 https://www.debuggex.com/r/Yxqws81Uif-BGBN8 Important note - this is built up programmatically, it's not just a string dumped in a parser! [1] http://www.w3.org/TR/n-triples/#n-triples-grammar http://www.w3.org/TR/n-triples/#n-triples-grammar
- psychometry 12y agoNow you have three problems.
- pg_is_a_butt 12y agoyou know what else can represent all regular expressions? regular expressions. #dumb
- jluxenberg 12y agoS-expressions are a natural fit for construction of regular expressions, see http://community.schemewiki.org/?scheme-faq-programming#H-1w56qpn http://community.schemewiki.org/?scheme-faq-programming#H-1w... e.g. (: (or (in ("az")) (in ("AZ"))) (* (uncase (in ("az09")))))
- maratd 12y agoRegular expressions are a natural fit for construction of regular expressions. Look, I know it takes a while, but once you get the hang of it, you won't need any crutches to write regular expressions. The only tool that's really needed is a way to rigorously test a regular expression to make sure it does what it needs to do and there are a ton of those around.
- skymt 12y agoAlternate representations of regexes aren't necessarily a crutch to avoid learning the normal syntax. S-expressions in particular could be useful for runtime manipulation or generation of patterns without the bother of string mangling. (I can't think of a reason to do so off-hand, but it's a nifty capability.)
- to3m 12y agoHere's an example of this kind of thing from some emacs lisp I wrote (which I hope survived the transition to the HN comment box): (setq imenu-generic-expression (let ((ident '(1+ (any "A-Za-z0-9_")))) `(("plugin" ,(rx line-start (0+ space) "plugin" (1+ space) (eval ident) (1+ space) (group (eval ident))) 1)))) Of course, you can do this with string concatenation, but I think this syntax makes it clearer what's going on.
- andrewflnr 12y agoNo, they're really not, as evidenced by all the quoting and meta-character nonsense you have to deal with. Sure, it's not too difficult to figure out, most of the time, but I think a solution that puts characters and logic on different quoting levels will almost always be better from an expressiveness standpoint (ignoring ecosystem issues).
- kazinator 12y agoYes, regexes can have other syntactic representations, like: (compound "$" (1+ :digit) "." :digit :digit) Run: $ txr -p "(regex-compile '(compound \"$\" (1+ :digit) \".\" :digit :digit))" #/$\d+\.\d\d/
- draegtun 12y agoThought this might be of interest; below shows how the examples provided would look in Rebol: digits: digit: charset "0123456789" rule: [ thru "$" some digits "." digit digit ] parse "$10.00" rule ;; true pattern: [ some "p" 2 "q" any "q" ] new-rule: [ 2 pattern ] parse "pqqpqq" new-rule ;; true Rebol doesn't have regular expressions instead it comes with a parse dialect which is a TDPL - http://en.wikipedia.org/wiki/Top-down_parsing_language http://en.wikipedia.org/wiki/Top-down_parsing_language Some parse refs: http://en.wikibooks.org/wiki/REBOL_Programming/Language_Features/Parse/Parse_expressions http://en.wikibooks.org/wiki/REBOL_Programming/Language_Feat... | http://www.rebol.net/wiki/Parse_Project http://www.rebol.net/wiki/Parse_Project | http://www.rebol.com/r3/docs/concepts/parsing-summary.html http://www.rebol.com/r3/docs/concepts/parsing-summary.html
- _lce0 12y agohey thanks to share! TIL Although Rebol can be used for programming, writing functions, and performing processes, its greatest strength is the ability to easily create domain-specific languages or dialects. — Carl Sassenrath [Rebol author] https://en.wikipedia.org/wiki/Rebol https://en.wikipedia.org/wiki/Rebol
- carlob 12y agoMathematica also has its own string pattern sytax http://reference.wolfram.com/language/ref/StringExpression.html http://reference.wolfram.com/language/ref/StringExpression.h... Something like that would be StringExpression[ "$", Repeated[DigitCharacter], ".", DigitCharacter, DigitCharacter ] or StringExpression[ "$", Repeated[DigitCharacter], ".", Repeated[DigitCharacter, {2}], ] or StringExpression[ "$", NumberString ] and the other is StringExpression[ Repeated[ StringExpression[ Repeated["p", {1, Infinity}], Repeated["q", {2, Infinity}] ], {2} ] ] This can be made more concise since StringExpression has an infix form (~~) and Repeated can sometimes be replaced by postfix ..
- epicureanideal 12y agoNice work! I don't know if it'll be ideal for all use cases, but it does add some readability.
- zzzcpan 12y agoRegexpes exist to avoid cumbersome code like this, to make it less error prone. Makes me sad to see so many upvotes. I get that some people have a hard time understanding regexpes with all the backtracking and greediness. Yes, syntax is a bit complicated. Maybe simplified predictable default mode could help. But there is no problem with DSL being used as an abstraction. In fact, we need more DSLs, for everything!
- otakucode 12y agoNow do an example where you create a regex to parse the IMDB movies.list data file!