regstr
Version:
JSON.stringify objects with RegExp properties and then JSON.parse json string resulted back into original objects. Converts RegExp object to be serializable - into pair of strings (key,value). Could be used for RegExp being bilaterally stringified and ge
344 lines (260 loc) • 11.5 kB
Plain Text
node ./docs/ciphering_explain.js
Package <regStr>
(serialization of objects and arrays containing regular expression objects.
JSON.stringify - JSON.parse - compatible)
Converts single RegExp object or some object with RegExp properties
to the form adequate to stringify and back parse them using JSON
by means of JSON.stringify and then JSON.parse back.)
----- Ciphering or conversion ------
The main concept is to cipher RegExp object into 'cipher' pair of strings
or cipher object - single property object, easily stringifiable,
and automatically recognizable after back parsing to get "initial"
object contained RegExp-s.
The easiest way to get acquaintance with module is to look at examples:
Loading handler from working directory ( using variable - h presumes
that module is a handler. Identifier regstr or any yourVar would be OK
as well):
var h=require('./regstr').regStr;
ciphering is provided by method h.streger() , like this:
var v=/asdf/gi;
/asdf/gi
h.streger( v ) or h.streger(/asdf/gi)
gives
{ RE15: 'asdfRE15gi' }
or an object
var o={a:/asdf/gim};
h.streger(o) or h.streger( {a:/asdf/gim} )
gives
{ aRE51: 'asdfRE51gmi' }
or an object inside an array
h.streger( [ {a:/asdf/gi},/^[+]+cc.*$/gim ] );
returns
[ { aRE05: 'asdfRE05gi' }, { '1RE86': '^[+]+cc.*$RE86gmi' } ]
or array with RegExp objects elements
h.streger( [
/asdf/gi,
/^[+]+cc.*$/gim,
/sdf/
]
);
[ { RE21: 'asdfRE21gi' },
{ '1RE19': '^[+]+cc.*$RE19gmi' },
{ '2RE87': 'sdfRE87' } ]
or object with RegExp objects properties
h.streger(
{ a: /asdf/gi,
b: /^[+]+cc.*$/gim,
ab:[{ bb:/sdfg/mg},/sdf/]
}
);
{ ab: [ { bbRE65: 'sdfgRE65gm' }, { '1RE55': 'sdfRE55' } ],
aRE23: 'asdfRE23gi',
bRE96: '^[+]+cc.*$RE96gmi' }
all these results are easily stringified and back parsed by
JSON.stringify and JSON.parse
Applying h.reger() method after parsing will bring RegEpx:
keeping in mind the process flow
ciphering deciphering
RegExp > h.streger > cipherObject > h.reger > RegExp
h.reger( h.streger({ a: /asdf/gi,
b: /^[+]+cc.*$/gim,
ab:[{ bb:/sdfg/mg},/sdf/] } )
);
gives:
{ ab: [ { bb: /sdfg/gm }, /sdf/ ],
a: /asdf/gi,
b: /^[+]+cc.*$/gim }
You already could have observed the letters 'RE' and few (two) digits after
it in strings representing keys and values ciphered. This is a mark
using in ciphering and identification ciphered regExp later. Digits are
random and their number could be changed by property h.nMin. For example
let's set it to 5.
h.nMin=5;
and the lay out of key and value strings will have changed. For ex.:
h.streger( { a: /asdf/gi,
b: /^[+]+cc.*$/gim,
ab:[{ bb:/sdfg/mg},/sdf/],
c:{re:/nnn.+$/gim,ar:[/aaa/,/bbb/g]}
}
);
returns:
{ ab: [ { bbRE06454: 'sdfgRE06454gm' }, { '1RE36099': 'sdfRE36099' } ],
c: { ar: [ [Object], [Object] ], reRE06638: 'nnn.+$RE06638gmi' },
aRE59825: 'asdfRE59825gi',
bRE00611: '^[+]+cc.*$RE00611gmi' }
The explanation regarding REn follows bellow. Here we just mention
that during deciphering different key-value pairs ciphering different
regexp-s could have different number of that random digits after 'RE'
like this:
var b=[ { aRE28: 'asdfRE28gi' }, { '1RE62555': '^[+]+cc.*$RE62555gmi' } ]
h.reger( b); will return
[ { a: /asdf/gi }, /^[+]+cc.*$/gim ]
Handler h (regstr) has h.replacer and h.reviver
methods that could be used to serialize and parse back objects and
arrays with RegExp-s without
direct intermediary of h.streger(...) and h.reger(...).
functions could be used
var replacer = h.replacer.bind(h);
var reviver = h.reviver.bind(h);
and
o -> o1 = JSON.stringify(o,replacer) ->
o = JSON.parse(o1,reviver)
compare o
[ { a: /asdf/gi }, /^[+]+cc.*$/gim ]
with
o=JSON.parse ( JSON.stringify(o,h.replacer.bind(h)), h.reviver.bind(h))
or
o=JSON.parse ( JSON.stringify(o,replacer), reviver)
[ { a: /asdf/gi }, /^[+]+cc.*$/gim ]
and with
h.reger( h.streger([{a:/asdf/gi},/^[+]+cc.*$/gim]) );
[ { a: /asdf/gi }, /^[+]+cc.*$/gim ]
Explanation:
Let's pO is some parent object with a property described by
(key,value) pair, where
value=pO[key]; // and value is regular expression object
(value instanceof RegExp===true)?true:false; // is true and
value=new RegExp(body,mig); // where body and mig are strings
{string}body - is string of regular expression and
{string}mig - RegExp flags - ( multi-line, insensitive, global)
Conversion algorithm features:
1. Additional property key1 is added to object pO -
pO[key1]=value1;
key1=key+RE; // value=new RegExp(body,mig) are converted into string
value1=body+RE+mig; // where
RE='RE'+rndm10;
and {string}rndm10 is random string consisted of 10 random digits
from 0-9 in each place, for ex.
rndm10='0987654321'; //
The number of random digit depends and could be any of your choice
rndm4, ..rndm2 ...
Obviously pO[key1] is serializable by JSON.
2. Or
delete pO[key];
or if you would not have done it yourself the JSON.stringify will do
during serialization
Inclusion of RE string into key1 and value1 is used as a mark
marking the property and permits to identify it during reverse
parse procedure and to transform
value1 string body+RE+mig into new RegExp(body,mig) :
Back Parsing features:
After JSON.parse( regExpJsoned )
1. Selects object string property containing in key and value
marking string RE==='RE'+rndmN ,
where N is number of digital positions in random rndmN N-digital string.
RE populates the ending positions of key( property name string) and
separates body-part from mig-part in property string value===body+RE+mig, so
var vs=pO[oid+RE].split(RE); // (5)
var newRegExpValue= new RegExp( vs[0],vs[1]); // (6)
when you would be needed to get RE you should look for a property
with string value, in (key,value) pair :
and
1. property name and property string value contain the same pattern RE
2. the property name has it located at the end of string
3. the value string consists of three parts: body,RE and mig
splitting the valueString by RE pattern body and mig -parts could be got
and therefor RegExp value be invoked
Package Usage for pO object:
var regstr=require('regstr).regStr; // handler object
variant A.
RegExp property conversions into string:
For each property being RegExp new converted string property
is created. Original ones keep safe.( are not deleted from object
if it's necessary do it yourself or use optional parameter opt_ciphMode
to manage this option)
pO=regstr.streger(pO); // Remark: changes of pO properties are accessible
// for external scope of stregger. Possible call is
// regstr.streger(pO);
variant B.
per single RegExp property transformation
var o;
// preJson step
for(var k in pO){
if( pO[k] instanceof RegExp){
o=regstr.reStr(pO[k],k);
// creates new property with new key and value {string}
pO[o.ky]=o.v;
}
}
// json.stringify
var jsonPo=JSON.stringify(pO)
// parse Back
detailed explanation see in deciphering_explain.txt of deciphering_explain.js-object
in docs directory.
to get it in console type: npm run explain
or inside node by require('./docs.deciphering_explain.js'); command
var oP=JSON.parse(jsonPo);
postParse properties' conversion into RegExp-s if any
variant 1.
All cyphered properties if are available are selected
and are converted to RegExp with new keys (by excluding RE from key):
oP=regstr.reger(oP);
// or Variant 2
// if 'property by property' handling is necessary
var ob;
for( var ip in oP){
if( typeof oP[ip]==='string'){
ob=regstr.regUp(oP[ip]);
if(ob.key!==ip){
// new RegExp property of oP
ob[ob.key]=ob.value;
delete oP[ip];
}
}
}
Remark 1.
RegExp object variable itself could be converted into
object with one property {RE:regString}
var regE=someRegExp; // someRegExp=new RegExp(body,mig);
var oStrReg=regstr.reStr(regE);
// var o=oStrReg.o(); where o={ RE: regString } where
// RE='RE'+rndmN , regString = body+RE+mig,
// at the same time RE=oStrReg.re;
// regString=oStrReg.c;
// body=oStrReg.b;
// mig=oStrReg.mig
//
Remark 2.
uncycle package extension. (miss it now, go further up to Decipher
method concept...)
This RegExp handling algorithm could be included in preStringify methods
of <uncycle> package -targeting to stringify objects with circular references
to provide extending functionality, or when json is used for cloning objects.
to switch it on set
unCycle.uiDirect.regOn=true;
.................................
Following comments are based on notion of uncycle package.
suppose some ith-property with (oid,uid,value) being RegExp
oid='oid'; // property's object id or key
uid='##x#x#...#oid'; // appropriate universal identifier of this property
If pO is this property's parent object,
property's value is RegExp object
pO[oid]=new RegExp(body,mig); // (1) {RegExp}
unCycle.uiDirect[uid]=new RegExp(body,mig); // (2) {RegExp}
to create new property for parent object with string value:
pO[oid+RE]=body+RE+mig; // (3) {string}
where RE='RE'+rndm10
and
rndm10='0987654321'; // -random string of 10 digits from 0-9 in each place
The number of random digit depends and could be any of your choise
rndm4, ..rendm2 ...
2. delete pO[oid]; // if you would no have done it yourself
// JSON.stringify will not do it but only
// would set empty appropriate object
3. appropriately, the uid of this new property will be
uidNewPr=uid+RE; // {string} and uiDirect object will contain property
unCycle.uiDirect[uid+RE]=body+RE+mig; // (4) {string}
Inclusion of RE string into oid and string value of newly created property
simplifies it's identification and following transformation of
body+RE+mig string into new RegExp(body,mig) :
var vs=pO[oid+RE].split(RE); // (5)
var newRegExpValue= new RegExp( vs[0],vs[1]); // (6)
when you would be need to get RE you should look for a property
with string value, i.e. for (key,value) :
(typeof value === 'string') && three remarkable points:
1. For newly created property - property name and
property string ciphered value contain the same pattern RE
2. the property name has it at the end of string
3. the value's body and mig string could be obtained splitting the
valueString by RE pattern
...........................................