qparser

A parsing library intended to parse complex user input

npm install qparser
8 downloads in the last week
16 downloads in the last month
<!DOCTYPE  html>
<html>
  <head>
    <meta charset="utf-8">
    
    <title>doc</title>
    <style>
      /*github.com style (c) Vasily Polovnyov <vast@whiteants.net>*/
      pre code {
        display: block; padding: 0.5em;
        color: #333;
        background: #f8f8ff
      }
      pre .comment,
      pre .template_comment,
      pre .diff .header,
      pre .javadoc {
        color: #998;
        font-style: italic
      }
      pre .keyword,
      pre .css .rule .keyword,
      pre .winutils,
      pre .javascript .title,
      pre .nginx .title,
      pre .subst,
      pre .request,
      pre .status {
        color: #333;
        font-weight: bold
      }
      pre .number,
      pre .hexcolor,
      pre .ruby .constant {
        color: #099;
      }
      pre .string,
      pre .tag .value,
      pre .phpdoc,
      pre .tex .formula {
        color: #d14
      }
      pre .title,
      pre .id {
        color: #900;
        font-weight: bold
      }
      pre .javascript .title,
      pre .lisp .title,
      pre .clojure .title,
      pre .subst {
        font-weight: normal
      }
      pre .class .title,
      pre .haskell .type,
      pre .vhdl .literal,
      pre .tex .command {
        color: #458;
        font-weight: bold
      }
      pre .tag,
      pre .tag .title,
      pre .rules .property,
      pre .django .tag .keyword {
        color: #000080;
        font-weight: normal
      }
      pre .attribute,
      pre .variable,
      pre .lisp .body {
        color: #008080
      }
      pre .regexp {
        color: #009926
      }
      pre .class {
        color: #458;
        font-weight: bold
      }
      pre .symbol,
      pre .ruby .symbol .string,
      pre .lisp .keyword,
      pre .tex .special,
      pre .prompt {
        color: #990073
      }
      pre .built_in,
      pre .lisp .title,
      pre .clojure .built_in {
        color: #0086b3
      }
      pre .preprocessor,
      pre .pi,
      pre .doctype,
      pre .shebang,
      pre .cdata {
        color: #999;
        font-weight: bold
      }
      pre .deletion {
        background: #fdd
      }
      pre .addition {
        background: #dfd
      }
      pre .diff .change {
        background: #0086b3
      }
      pre .chunk {
        color: #aaa
      }
    </style>
  </head>
  <body>  
    <h1 id="qparser">QParser</h1>
<p>A parsing library intended to parse complex user input with logical operators, grouping, prefixes and flags.</p>
<p>Written by Vladimir Neverov <a href="&#109;&#97;&#105;&#108;&#116;&#x6f;&#58;&#115;&#97;&#x6e;&#x67;&#x75;&#x69;&#x6e;&#x69;&#64;&#x67;&#x6d;&#x61;&#105;&#x6c;&#46;&#99;&#x6f;&#109;">&#115;&#97;&#x6e;&#x67;&#x75;&#x69;&#x6e;&#x69;&#64;&#x67;&#x6d;&#x61;&#105;&#x6c;&#46;&#99;&#x6f;&#109;</a> in 2013.</p>
<p>Wiki: <a href="https://github.com/vne/qparser/wiki">https://github.com/vne/qparser/wiki</a></p>
<h1 id="usage">Usage</h1>
<p>The library is intended for parsing an arbitrary user text input into tokens that can be easily
converted to a query to a database. User text input is much like the thing you write
in Google to do a complex search, e.g. &quot;animals -bears&quot; or &quot;bears OR monkeys&quot;. The parser
allows the logical expressions like OR and AND as well as grouping like in math equations.
It also allows prefixes, range queries, quoted strings and various flags.</p>
<p>QParser can be used both in NodeJS and in browser.</p>
<p>You feed the parser with the text string and it returns an array of objects, each object describing
one token. Tokens can be of the following types:</p>
<ul>
<li>range - a range query, e.g. &quot;20-30&quot; or &quot;-50&quot; or &quot;45-&quot;</li>
<li>prefix - a string with a prefix separated by colon, e.g. &quot;site:wikipedia.org&quot;</li>
<li>prange - prefixed range, e.g. &quot;price:100-200&quot;</li>
<li>string - any other input, e.g. arbitrary strings and numbers</li>
<li>or - a group of queries that should be logically ORed, e.g. &quot;love|hate&quot;</li>
<li>and - a group of queries that should be logically ANDed, e.g. &quot;(jim morrisson)&quot;
It&#39;s your choice how to process this array of objects. It can be converted to an SQL query,
to a query to a NoSQL database, etc.</li>
</ul>
<h2 id="simple-cases-of-search-input">Simple cases of search input</h2>
<pre><code>&gt; bears monkeys</code></pre>
<p>This will produce an array of two objects:</p>
<pre><code>&gt; [
&gt;    { type: &quot;string&quot;, query: &quot;bears&quot; },
&gt;    { type: &quot;string&quot;, query: &quot;monkeys&quot; }
&gt; ]

&gt; bears !monkeys</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;string&quot;, query: &quot;bears&quot; },
&gt;    { type: &quot;string&quot;, query: &quot;monkeys&quot;, flags: [&quot;!&quot;] }
&gt; ]

&gt; animal:bears</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;prefix&quot;, prefix: &quot;animal&quot;, query: &quot;bears&quot; }
&gt; ]

&gt; bears 300-500</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;string&quot;, query: &quot;bears&quot; },
&gt;    { type: &quot;range&quot;, from: 300, to: 500 }
&gt; ]

&gt; bears price:20-30</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;string&quot;, query: &quot;bears&quot; },
&gt;    { type: &quot;prange&quot;, prefix: &quot;price&quot;, from: 20, to: 30 }
&gt; ]</code></pre>
<p>All special symbols can be screened with backslash.</p>
<h2 id="grouping">Grouping</h2>
<p>Round brackets group everything inside them into a single logical term. The content
is ANDed. Example:</p>
<pre><code>&gt; (sex drugs)|rocknroll</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;     {
&gt;         type: &quot;or&quot;,
&gt;         queries: [
&gt;             {
&gt;                 type: &quot;and&quot;,
&gt;                 queries: [
&gt;                     {
&gt;                         type: &quot;string&quot;,
&gt;                         query: &quot;sex&quot;
&gt;                     },
&gt;                     {
&gt;                         type: &quot;string&quot;,
&gt;                         query: &quot;drugs&quot;
&gt;                     }
&gt;                 ]
&gt;             },
&gt;             {
&gt;                 type: &quot;string&quot;,
&gt;                 query: &quot;rocknroll&quot;
&gt;             }
&gt;         ]
&gt;     }
&gt; ]</code></pre>
<p>Square brackets also group everything inside them, but the content is ORed. Example:</p>
<pre><code>&gt; [sex drugs] rocknroll</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;     {
&gt;         type: &quot;or&quot;,
&gt;         queries: [
&gt;            {
&gt;                type: &quot;string&quot;,
&gt;                query: &quot;sex&quot;
&gt;            },
&gt;            {
&gt;                type: &quot;string&quot;,
&gt;                query: &quot;drugs&quot;
&gt;            }
&gt;         ]
&gt;     },
&gt;    {
&gt;        type: &quot;string&quot;,
&gt;        query: &quot;rocknroll&quot;
&gt;    }
&gt; ]</code></pre>
<h2 id="more-on-flags-strings-and-spaces">More on flags, strings and spaces</h2>
<p>Each token in an input string can be prefixed by an arbitrary number of flags. By default,
flags are symbols from the following list: ~, \, +, #, !, *, /, \
Default list can be altered, see API.
Example:</p>
<pre><code>&gt; ~\+#!*\/animal:bear</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;prefix&quot;, prefix: &quot;animal&quot;, query: &quot;bear&quot;, flags: [&quot;~&quot;, &quot;\&quot;, &quot;&quot;, &quot;+&quot;, &quot;#&quot;, &quot;!&quot;, &quot;*\&quot;, &quot;/&quot;] }
&gt; ]</code></pre>
<p>Flags in the array will appear in the same order as in the input string. Flags are not interpreted in any
way, it is up to you to decide what does each flag mean.</p>
<p>Everywhere where a string can appear, a quoted string can be used. E.g.</p>
<pre><code>&gt; &quot;bears monkeys&quot;</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;string&quot;, query: &quot;bears monkeys&quot; }
&gt; ]

&gt; animal:&quot;white bears&quot;</code></pre>
<p>will produce</p>
<pre><code>&gt; [
&gt;    { type: &quot;prefix&quot;, prefix: &quot;animal&quot;, query: &quot;white bears&quot; }
&gt; ]</code></pre>
<p>By default, the following symbols are recognized as quotes: &quot;, &#39;, `
This can be changed through API. If the quote is not closed, then
the string will take everything until the end of the input.</p>
<p>Spaces divide tokens, if not inside quotes. E.g.</p>
<pre><code>&gt; bears monkeys</code></pre>
<p>will produce two tokens. The same input in quotes will produce one token. By default,
the following symbols are recognized as spaces: \r, \n, \t and space itself. This can be
changed, ses API.</p>
<h1 id="api">API</h1>
<p>First you should require the library:</p>
<pre><code>&gt; var qparser = require(&#39;qparser&#39;);</code></pre>
<p>Next, you should instantiate the parser:</p>
<pre><code>&gt; var parser = new qparser();</code></pre>
<p>Finally, you can use it to parse strings:</p>
<pre><code>&gt; var tokens = parser(&quot;arbitrary user input&quot;);</code></pre>
<p>So, require returns a class, instantiating with &#39;new&#39; returns a parser function. The latter is not common case,
usually &#39;new&#39; returns a new instance. If you require an instance of the parser, you can pass an argument:</p>
<pre><code>&gt; var parserInstance = new qparser({ instance: true });</code></pre>
<p>This can be used as followes:</p>
<pre><code>&gt; var tokens = parserInstance.parse(&quot;user input&quot;);</code></pre>
<p>Besides &#39;instance&#39;, constructor accepts the following options:</p>
<ul>
<li>quotes           - symbols that are recognized as quotes (defaults are &#39;, &quot; and `)</li>
<li>spaces           - symbols that are recognized as spaces (defaults are <space>, &#39;\t&#39;, &#39;\r&#39; and &#39;\n&#39; )</li>
<li>flags            - symbols that are recognized as flags (defaults are &#39;~&#39;, &#39;+&#39;, &#39;#&#39;, &#39;!&#39;, &#39;*&#39; and &#39;/&#39; )</li>
<li>screen           - symbols that are recognized as screen (default is &#39;\&#39; )</li>
<li>group_open       - symbols that are recognized as group openers (default is &#39;(&#39; )</li>
<li>group_close      - symbols that are recognized as group endings (default is &#39;)&#39; )</li>
<li>or               - symbols that are recognized as logical OR (default is &#39;|&#39; )</li>
<li>prefix           - symbols that are recognized as divider between prefix and value (default is &#39;:&#39; )</li>
<li>range            - symbols that are recognized as divider between first and second values in range (default is &#39;:&#39; )</li>
<li>or_open          - symbols that are recognized as OR group openers (default is &#39;[&#39;)</li>
<li>or_close         - symbols that are recognized as OR group endings (default is &#39;]&#39;)</li>
</ul>
<p>Each of these options can be either a regular expression or a string containing all symbols
that will be treated as quotes, spaces, flags etc respectively. Unfortunately, special symbols should be
characters, therefore, you can not use, for example, &#39; OR &#39; for logical ORs.
If an option is a regular expression, than it will be used to test if a symbol is something special. E.g.</p>
<pre><code>&gt; var parser = new qparser({ quotes: &#39;&quot;&#39;, spaces: &quot;\t&quot; });</code></pre>
<p>will produce a parsing function that will only recognize &quot; as a quote and \t as token delimeter.</p>
<h1 id="tests-and-examples">Tests and examples</h1>
<p>More examples of library usage can be found in <strong>test.js</strong> file. To run tests you will
need <a href="http://visionmedia.github.io/mocha/">Mocha</a>, the tests themselves use built-in
NodeJS <a href="http://nodejs.org/api/assert.html">assert</a> module. To run tests in browser
open <strong>test.html</strong> file.</p>

  </body>
</html>
npm loves you