npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

stringscanner

v0.0.3

Published

Stringscanner performs lexical scanning operations on a string.

Downloads

10

Readme

StringScanner

StringScanner performs lexical scanning operations on a string. Inspired by Ruby's StringScanner class

How To Use

Instantiate a new StringScanner by passing its constructor the string to scan.

var StringScanner = require("StringScanner");
var ss = new StringScanner("abc123 def456");
// #<StringScanner 0/13 @ "abc12...">

For the following examples, ss represents the StringScanner instance defined above.

bol / beginningOfLine

Returns true if the scan pointer is at the beginning of a line (right after \n) or the beginning of the string, false otherwise.

ss.reset()    // #<StringScanner 0/13 @ "abc12...">
ss.pointer()  // 0
ss.bol()      // true
ss.scan(/./)  // "a"
ss.pointer()  // 1
ss.bol()      // false

captures

Returns an Array containing the contents of the capturing groups in the last evaluated pattern match.

ss.reset()              // #<StringScanner 0/13 @ "abc12...">
ss.check(/.*(..) (..)/  // "abc123 de"
ss.captures()           // ["23","de"]
ss.check(/\w+/)         // "abc123"
ss.captures()           // []
ss.check(/\s+/)         // null
ss.captures()           // []

check(pattern)

Note: this method alters last match results

Checks if a scan of the given pattern would succeed without advancing the scan pointer. Returns the portion of the string matched on successful match, null otherwise.

ss.reset()           // #<StringScanner 0/13 @ "abc12...">
ss.check(/[a-z]+/i)  // "abc"
ss.check(/[a-z]+/i)  // "abc"
ss.scan(/[a-z]+/i)   // "abc"
ss.check(/[a-z]+/i)  // null
ss.check(/[\d\s]+/)  // "123 "

checkUntil(pattern)

Note: this method alters last match results

Checks if a scanUntil would succeed without advancing the scan pointer. Returns the portion of the string being scanned from the scan pointer to the end of the matched string on successful match, null otherwise.

ss.reset()           // #<StringScanner 0/13 @ "abc12...">
ss.checkUntil(/\s/)  // "abc123 "
ss.checkUntil(/\s/)  // "abc123 "
ss.checkUntil(/r/)   // null
ss.scanUntil(/e/)    // "abc123 de"
ss.checkUntil(/\s/)  // null

clone / dup

Creates a duplicate of this instance of StringScanner.

concat(str)

Appends the given string to the string being scanned.

ss.reset()            // #<StringScanner 0/13 @ "abc12...">
ss.checkUntil(/h/)    // null
ss.concat(" ghi789")  // #<StringScanner 0/20 @ "abc12..."
ss.checkUntil(/h/)    // "abc123 def456 gh"

eos / endOfString

Returns true if the scan pointer is at the end of the string being scanned, false otherwise.

ss.reset()     // #<StringScanner 0/13 @ "abc12...">
ss.pointer()   // 0
ss.eos()       // false
ss.scan(/.*/)  // "abc123 def456"
ss.pointer()   // 13
ss.eos()       // true

exists(pattern) / exist(pattern)

Note: this method alters last match results

Warning: this method may return 0 on a successful operation. Use === comparision to null for failure check, for example: ss.exists(/a/i)===null

Checks if the given pattern matches anywhere after the current scan pointer. This will determine if a scanUntil operation will succeed. Returns the number of characters between the scan pointer and the position in which the match was found on success, null otherwise.

ss.reset()
// ----
ss.exists(/c/)   // 2
ss.match()       // "c"
ss.matched()     // true
// ----
ss.exists(/a/)   // 0
ss.match()       // "a"
ss.matched()     // true
// ----
ss.exists(/b*/)  // 0
ss.match()       // ""
ss.matched()     // true
// ----
ss.exists(/m/)   // null
ss.match()       // null
ss.matched()     // false

getch / getChar

Note: this method alters last match results

Note: Ruby equivalent: get_byte

scans one character and returns it; exactly equivalent to scan(/./).

ss.reset()    // #<StringScanner 0/13 @ "abc12...">
ss.getch()    // "a"
ss.reset()    // #<StringScanner 0/13 @ "abc12...">
ss.scan(/./)  // "a"

match

Note: Ruby equivalent: matched

Returns the last string matched or null if the last attempted match failed.

ss.reset()           // #<StringScanner 0/13 @ "abc12...">
ss.scan(/[a-z]+/i)   // "abc"
ss.match()           // "abc"
ss.check(/[a-z]+/i)  // null
ss.match()           // null

matches(pattern)

Note: Ruby equivalent: match?

Checks if a scan of the given pattern would succeed without advancing the scan pointer. Returns the length of the string matched on successful match, null otherwise.

ss.reset()             // #<StringScanner 0/13 @ "abc12...">
ss.matches(/[a-z]+/i)  // 3
ss.matches(/[a-z]+/i)  // 3
ss.scan(/[a-z]+/i)     // "abc"
ss.matches(/[a-z]+/i)  // null
ss.matches(/[\d\s]+/)  // 4

matched

Note: Ruby equivalent: matched?

Returns true if the last attempted match was successful, false otherwise.

ss.reset()      // #<StringScanner 0/13 @ "abc12...">
ss.scan(/\w+/)  // "abc123"
ss.matched()    // true
ss.scan(/\w+/)  // null
ss.matched()    // false

matchSize

Warning: this method may return 0 on a successful operation. Use === comparision to null for failure check, for example: ss.matchSize()===null

Returns the length of the most recently matched string if the most recent match attempt succeeded, null otherwise.

ss.reset()       // #<StringScanner 0/13 @ "abc12...">
ss.scan(/\w+/)   // "abc123"
ss.matchSize()   // 6
ss.check(/\w*/)  // ""
ss.matchSize()   // 0
ss.check(/\w+/)  // null
ss.matchSize()   // null

peek(len)

Returns len characters after the scan pointer, or the rest of the string, whichever is shorter.

ss.reset()      // #<StringScanner 0/13 @ "abc12...">
ss.scan(/.*d/)  // "abc123 d"
ss.peek(3)      // "ef4"
ss.peek(9001)   // "ef456"
ss.peek(0)      // ""
ss.peek(-3)     // ""

pointer / position

Returns the scan pointer position as an integer.

ss.reset()            // #<StringScanner 0/13 @ "abc12...">
ss.pointer()          // 0
ss.scan(/\w+\d+\s+/)  // "abc123 "
ss.pointer()          // 7
ss.scan([a-z]+)       // "def"
ss.pointer()          // 10

setPointer(pos)

Manually move the scan pointer to pos characters from the beginning of the string. The scan pointer is bounded between zero and the scanning string's length. Returns the position to which the scan pointer was moved. setPointer neither resets nor modifies the last match results.

ss.reset()         // #<StringScanner 0/13 @ "abc12...">
ss.setPointer(4)   // 4
ss.scan(/\d+/)     // "23"
ss.pointer()       // 6
ss.setPointer(-4)  // 0
ss.setPointer(99)  // 13

reset

Moves the scan pointer back to the beginning of the string being scanned and clears the last match results.

ss.reset()            // #<StringScanner 0/13 @ "abc12...">
ss.scanUntil(/(\s)/)  // "abc123 "
ss.pointer()          // 7
ss.match()            // "abc123 "
ss.captures()         // [" "]
ss.reset()            // #<StringScanner 0/13 @ "abc12...">
ss.pointer()          // 0
ss.match()            // null
ss.captures()         // []

rest

Returns the portion of the string being scanned after the scan pointer.

ss.reset()          // #<StringScanner 0/13 @ "abc12...">
ss.scanUntil(/\s/)  // "abc123 "
ss.rest()           // "def456"

scan(pattern)

Note: this method alters last match results

Attempts to match the given pattern at the position of the scan pointer. Returns the matched string and advances the string pointer upon successful match. A failed match will result in a null value being returned.

ss.reset()         // #<StringScanner 0/13 @ "abc12...">
ss.scan(/[a-z]+/)  // "abc"
ss                 // #<StringScanner 3/13 @ "abc12...">
ss.scan(/[a-z]+/)  // null
ss                 // #<StringScanner 3/13 @ "abc12...">
ss.scan(/[0-9]+/)  // "123"
ss                 // #<StringScanner 6/13 @ "abc12...">

scanUntil(pattern)

Note: this method alters last match results

Attempts to match the pattern against the string being scanned. On a successful match, the scan pointer is advanced to the end of the matched portion of the string and the portion of the string being scanned up to and including the matched string is returned. On a failed match, null is returned.

ss.reset()         // #<StringScanner 0/13 @ "abc12...">
ss.scanUntil(/ /)  // "abc123 "
ss.scanUntil(/f/)  // "def"
ss.scanUntil(/f/)  // null

skip(pattern)

Note: this method alters last match results

Performs a scan, returning the length of the matched string on successful match, null otherwise.

ss.reset()         // #<StringScanner 0/13 @ "abc12...">
ss.skip(/[a-z]+/)  // 3
ss.skip(/[a-z]+/)  // null
ss.skip(/[0-9]+/)  // 3

skipUntil(pattern)

Note: this method alters last match results

Performs a scanUntil, returning the length of the matched string on successful match, null otherwise.

ss.reset()         // #<StringScanner 0/13 @ "abc12...">
ss.skipUntil(/ /)  // 7
ss.skipUntil(/f/)  // 3
ss.skipUntil(/f/)  // null

string

Returns the entire string being scanned.

ss.string()  // "abc123 def456"
ss.getch()   // "a"
ss.string()  // "abc123 def456"

terminate / clear

Advances the scan pointer to the end of the string being scanned and resets the last match results.

ss.reset()      // #<StringScanner 0/13 @ "abc12...">
ss.getch()      // "a"
ss.pointer()    // 1
ss.terminate()  // #<StringScanner fin>
ss.pointer()    // 13
ss.eos()        // true
ss.match()      // null

Known Issues

Not really an issue, but StringScanner assumes the global flag (g) is disabled on any RegExp objects passed as patterns to any of its methods. If the global flag is enabled, StringScanner may produce unexpected results.

Additional Info

I am always open for feature requests or any feedback. I can be reached at Github.

Thanks to the Ruby community for the original idea and implementation.