natefaubion / matches.js

Powerful pattern matching for Javascript
MIT License
772 stars 37 forks source link

Extensibility #2

Closed studgeek closed 12 years ago

studgeek commented 12 years ago

Any suggestions on the best way to extend the matching patterns? Perhaps to add a domain specific set of patterns (URLs , phone numbers, etc)?

natefaubion commented 12 years ago

Extending the patterns you are able to match on within the pattern "language" would require a dynamically extendable parser and compiler, which matches.js does not currently support. The parser is generated with pegjs, so its static.

But what it sounds like you are wanting to do is string validation/extraction which is best handled with regular expressions. String validation with regular expressions is really outside the scope of pattern matching implementations. Pattern matching is designed to let you check a for a type and potentially inspect its structure.

One way you could do what you want is to first parse your input string into some sort of structure, and then pass it to your function which could then match on that structure. Here is an example using Scala: http://ikaisays.com/2009/04/04/using-pattern-matching-with-regular-expressions-in-scala/

The gist being that he defines a regular expression that looks for certain patterns and returns an object with those attributes. He then matches on that object to pull out those values. Your type could be as simple as an object literal with certain attributes, or you could use something like adt.js (another library of mine) to define specific types (matches.js has great support for adt.js)

The way matches.js is currently extendable is to write your own pattern matching functions, and compose them together using combinators. If you look under the usage section at the third example, you'll see how you can do that.

function parseURL (args) {
  // tries to parse a url
}

function parsePhone (args) {
  // tries to parse a phone number
}

function parseAddress (args) {
  // tries to parse an address
}

var myfun =
  pattern(parseURL, function (url) { ... })
     .alt(parsePhone, function (phone) { ... })
     .alt(parseAddress, function (address) { ... });
studgeek commented 12 years ago

I was actually thinking of using it with xpath/jxpath against XML/Java structures. The idea isn't fully baked in terms of using it with matches.js, but I wanted to at least understand how to extend it. Thanks for the info!

natefaubion commented 12 years ago

0.4.0 release has a new feature for extending matches with your own custom extractors.

studgeek commented 12 years ago

Cool, thanks!