JSPM

  • Created
  • Published
  • Downloads 876
  • Score
    100M100P100Q84081F
  • License MIT

Replace strings with optional lookarounds, but without regexes

Package Exports

  • easy-replace

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (easy-replace) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

easy-replace

Standard JavaScript

string replacement with positive and negative lookahead and lookbehind, no regexes

Emphasis on no regexes

Build Status Coverage Status bitHound Overall Score bitHound Dependencies bitHound Dev Dependencies Downloads/Month

Table of Contents

Install

$ npm install --save easy-replace

Usage

The ideal use case for easy-replace is when you need complex lookarounds, such as "replace this only when there is something on the left, but also, if there's some things on the right, include them too, yet there can't be such and such on the right". Yes, you could solve this using a regex, but it's faster to skip regex solutions and simply use this library.

API

er(source_string, options_object, replacement_string)

API - Input

Input argument Type Obligatory? Description
source_string String yes Original string
options_object Plain Object yes Settings
replacement_string String no Replace all the findings with this. If missing, library runs on delete-only mode, it won't replace, just delete.

Options object:

Options object's key Type Obligatory? Description
{
leftOutsideNot String/Array of strings no Equivalent of regex negative lookbehind. This/these string(s) must not be present to the left of searchFor (plus any "maybe's" strings, see below), in order for searchFor to be counted as "found". This input's contents are not replaced/deleted.
leftOutside String/Array of strings no Equivalent of regex positive lookbehind. This/these string(s) must be present to the left of searchFor (plus any "maybe's" strings, see below), in order for searchFor to be counted as "found". This input's contents are not replaced/deleted.
leftMaybe String/Array no If this is present on the left side of the searchFor, replace/delete it together with searchFor, but don't fret if it's not found.
searchFor String only yes The keyword to look for in the source_string
rightMaybe String/Array of strings no If this is present on the right side of the searchFor, replace/delete it together with searchFor, but don't fret if it's not found.
rightOutside String/Array of strings no Equivalent of regex positive lookahead. This/these string(s) must be present to the right of searchFor (plus any "maybe's" strings, see higher), in order for searchFor to be counted as "found". This input's contents are not replaced/deleted.
rightOutsideNot String/Array of strings no Equivalent of regex negative lookahead. This/these string(s) must not be present to the right of searchFor (plus any "maybe's" strings, see higher), in order for searchFor to be counted as "found". This input's contents are not replaced/deleted.
}

API - Output

Type Description
String String with things replaced

Examples

Simple replace:

  • Example replacement recipe in words — replace all instances of x with 🦄.

  • Solution using this library::

var er = require('easy-replace');

er(
  'a x c x d',
  {
    leftOutsideNot: '',
    leftOutside: '',
    leftMaybe: '',
    searchFor: 'x',
    rightMaybe: '',
    rightOutside: '',
    rightOutsideNot: ''
  },
  '🦄'
);
//=> 'a 🦄 c 🦄 d'

"Maybes" — optional surrounding strings to be replaced as well

  • Example replacement recipe in words — Replace all instances of i. If there are 🐴 or 🦄 characters on the left, count them as part of found i and replace together as one thing. If there are 🐴 or 🦄 characters on the right, count them as part of found i and replace together as one thing.

  • Solution using this library::

var er = require('easy-replace');

er(
  '🐴i🦄 🐴i i🦄 i',
  {
    leftOutsideNot: '',
    leftOutside: '',
    leftMaybe: ['🐴', '🦄'],
    searchFor: 'i',
    rightMaybe: ['🐴', '🦄'],
    rightOutside: '',
    rightOutsideNot: ''
  },
  'x'
);
//=> 'x x x x'

By the way, notice, how the values can be strings or arrays! The easy-replace doesn't accept array only for searchFor values — create a loop from the outside of this library, then call this library many times if you want to search for multiple values.


Negative lookahead - if you want to match something not followed by something else

  • Example replacement recipe in words — Replace all instances of 🦄, but only ones that don't have c or d on the right.

  • Solution using this library::

var er = require('easy-replace');

er(
  'a🦄c x🦄x',
  {
    leftOutsideNot: '',
    leftOutside: '',
    leftMaybe: '',
    searchFor: '🦄',
    rightMaybe: '',
    rightOutside: '',
    rightOutsideNot: ['c', 'd']
  },
  '🐴'
);
//=> 'a🦄c x🐴x'

Positive lookbehind - if you want to match something that is preceded by something else

For example, search for space characters that have another space right to their left, and delete them

  • Example replacement recipe in words — Replace all occurencies of space character, but only those that have another space character in front of them.

  • Solution using this library::

var er = require('easy-replace');

er(
  'zzzzz  zzzzzz zzzzzz',
  {
    leftOutsideNot: '',
    leftOutside: ' ',
    leftMaybe: '',
    searchFor: ' ',
    rightMaybe: '',
    rightOutside: '',
    rightOutsideNot: ''
  },
  ''
);
//=> 'zzzzz zzzzzz zzzzzz'

Negative lookbehind* - if you want to match something that is not preceded by something else

For example, our <br /> sometimes look like <br/>. Replace all occurencies of /> with {{space character}}/> (disregard curly braces, it's only to make it more visible here) if they are not preceded with space already:

  • Example replacement recipe in words — Add missing spaces before closing slashes on tags. Do not add spaces where they exist already.

  • Solution using this library::

var er = require('easy-replace');

er(
  '<br /><br/><br />',
  {
    leftOutsideNot: ' ',
    leftOutside: '',
    leftMaybe: '',
    searchFor: '/>',
    rightMaybe: '',
    rightOutside: '',
    rightOutsideNot: ''
  },
  ' />'
);
//=> '<br /><br /><br />'

Real life scenario

  • Example replacement recipe in words — Add a missing semicolon and/or ampersand on &nbsp;, but only where they are missing.

  • Solution using this library::

var er = require('easy-replace');

er(
  '&nbsp; nbsp &nbsp nbsp;',
  {
    leftOutsideNot: '',
    leftOutside: '',
    leftMaybe: '&',
    searchFor: 'nbsp',
    rightMaybe: ';',
    rightOutside: '',
    rightOutsideNot: ''
  },
  '&nbsp;'
);
//=> '&nbsp; &nbsp; &nbsp; &nbsp;'

Rationale

Positive lookbehind and negative lookbehind are not supported in native JavaScript (at least in what we count as "classic" JavaScript, not ES2030 or something). Plus I find complex regexes, well, complex. Hence this library. I hope it is still simple-enough to bear 'easy' in its name.

Did I mention that this library is astral-character-friendly? As you noticed in the examples above, it accepts emoji perfectly fine (and AVA tests prove this).

It's impossible to cause an infinite loop on this library (see tests 8.1-8.6).

Library is also friendly if any input is of a number type — numbers are converted and replaced string is returned in string type (see test 10.8). That's extra convenience.

Options object is fool-proof — you can omit keys or pass non-existing ones or pass non-string type variables — if the options key matches, it's first turned into string. You can even omit any or all of the inputs — library will return an empty string (see tests 9.1–9.6).

Same with replacment — empty, null, boolean or undefined are accepted and interpreted as a request to delete any results found. There's no replacement, only deletion in such case (see tests 10.1–10.7).

Testing

$ npm test

Unit tests use AVA and JS Standard notation.

Contributing

All contributions are welcome. Please stick to Standard JavaScript notation and supplement the test.js with new unit tests covering your feature(s).

If you see anything incorrect whatsoever, do raise an issue. If you file a pull request, I'll do my best to help you to get it merged in a timely manner. If you have any comments on the code, including ideas how to improve things, don't hesitate to contact me by email.

Licence

MIT License (MIT)

Copyright (c) 2017 Codsen Ltd, Roy Reveltas

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.