Find and replace complex term in a string using Regex - javascript

I Need to wrap any expression in a string (it can be multiline string with many expressions, mixed with regular words) that starts with abc.(efg|xyz).bar. with curly braces.
I'm using find and replace approach using the following Regex:
const MY_REGEX = /"?(?<![a-zA-Z0-9-_])((?:abc\.(efg|xyz\.bar))(?:\.[a-zA-Z0-9-_]*)+)"?/gm
someInput.replace(MY_REGEX, '{{$1}}')
My strategy works fine for simple cases like this:
const input = 'abc.efg.bar.name.first, abc.xyz.role, non.captured.term'
// outputs: {{abc.efg.bar.name.first}}, {{abc.xyz.role}}, non.captured.term
But fails miserably for a complex inputs like this one:
const input = 'abc.xyz.bar.$func(foos[param[name="primary" and bool=true]].param[name="new"].multiValue)'
// outputs: {{abc.xyz.bar.}}$func(foos[param[name="primary" and bool=true]].param[name="new"].multiValue)
// Should be: {{abc.xyz.bar.$func(foos[param[name="primary" and bool=true]].param[name="new"].multiValue)}}
I'm looking for a more robust way or better regex to do it.
Any suggestions?

Based on the examples you gave, it looks like , should be the delimiter between expressions. So (?:\.[a-zA-Z0-9-_]*)+) to [^,]* to match everything until the next ,.
const MY_REGEX = /"?(?<![a-zA-Z0-9-_])((?:abc\.(efg|xyz\.bar))[^,]*)"?/gm;
console.log('abc.xyz.bar.$func(foos[param[name="primary" and bool=true]].param[name="new"].multiValue)'.replace(MY_REGEX, '{{$1}}'));
console.log('abc.efg.bar.name.first, abc.xyz.role, non.captured.term'.replace(MY_REGEX, '{{$1}}'));

Related

Rewriting javascript regex in php when regex have escapes

I'm trying to write my regex as string (it's part of my S-Expression tokenizer that first split on string, regular expressions and lisp comments and then tokenize stuff between), it works in https://regex101.com/r/nH4kN6/1/ but have problem to write it as string for php.
My JavaScript regex look like this:
var pre_parse_re = /("(?:\\[\S\s]|[^"])*"|\/(?! )[^\/\\]*(?:\\[\S\s][^\/\\]*)*\/[gimy]*(?=\s|\(|\)|$)|;.*)/g;
I've tried to write this regex in php (the one from Regex101 was inside single quote).
$pre_parse_re = "%(\"(?:\\[\\S\\s]|[^\"])*\"|/(?! )[^/\\]*(?:\\[\\S\\s][^/\\]*)*/[gimy]*(?=\\s|\\(|\\)|$)|;.*)%";
My input
'(";()" /;;;/g baz); (baz quux)'
when called:
$parts = preg_split($pre_parse_re, $str, -1,
PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
it should create same array as in Regex101 (3 matches and stuff between) but it keep splitting on first semicolon inside regex /;;;/g
I think your escaping might be incorrect. Try this regex instead:
$pre_parse_re = "%(\"(?:\\\\[\\\\S\\\\s]|[^\"])*\"|\/(?! )[^\/\\\\]*(?:\\\\[\S\s][^\/\\\\]*)*\/[gimy]*(?=\s|\(|\)|$)|;.*)%";
Using preg_split might also return more than the capturing groups that you want, so you could also change to use this if you just want the 3 matches.
$parts;
preg_match_all($pre_parse_re, $str, $parts, PREG_SET_ORDER, 0);

splitting string as per regex in typescript is not working as expected for multiple space

In typescript I want to divide a name as per space. So, I used something like this
const splitted = name.split(' ');
It is working as expected, but if wrongly someone gave more than one space. So, i tried to handle multiple space to split. Like this,
const splitted = name.split('\\s+');
But, it is taking the whole string as 1 And, length of splitted varabel it is showing 1
It is working in java
Any explanation?
If you want to split along a regular expression, you need to pass an actual regular expression to split:
const splitted = name.split(/\s+/);
Your current code will split along a literal backslash, followed by a literal s and +, eg:
const name = 'foo\\s+bar';
const splitted = name.split('\\s+');
// splitted: ['foo', 'bar'];
You have to use backslash no quote when usign Regex:
const splitted = name.split(/\s+/g);

Javascript regex to find a particular string which could be broken across multiple lines

I'm trying to write a regex which gets a particular substring from a string. However, the substring could be broken across multiple lines.
I've tried using the multiline flag, like this:
"foo\nbar".match(/foobar/m)
But that returns null.
I've also seen a number of posts suggesting I use [\S\s]. However, as far as I can tell, this only works if you know where the break line will be, like this:
'foo\nbar'.match(/foo[\S\s]bar/m)
Is there a way to find all instaces of foobar in a string when the line break could anywhere in the string?
Is there a way to find all instances of foobar in a string when the line break could anywhere in the string?
Remove all line-breaks from subject before comparing with your regex.
See this simple demo:
const arr = ["foo\nbar", "\nfoobar", "fo\nobar", "foobar\n", "foobar"];
const val = 'foobar';
arr.forEach(function(el) {
console.log(el.replace(/\n/, '') == val)
});

split string of chain functions with reg-exp

I looked around on StackOverflow but could not find the answer!
Anyway, I was wondering how do I get following in JavaScript with regexp.
I have a string
bla().func1($(ele).attr("data")).func2.func3("test")... ;
and I want extract func1, func2, func3... from the given string, anybody have an example of how to do that?
Bear in mind, that the function names changes, so they are not func1, func2 ... they can be load, past, moon ... whatever
try this:
var str = 'bla().func1($(ele).attr("data")).func2("test")';
alert(str.split(/(?:\.)\w+\d+(?=\()/g));
There's the fiddle:
http://jsfiddle.net/cv6avhfb/3/
This code would split the string in parts while using as separators substrings like '.func1(', '.func2(', '.abc3(' and other. If the function names have different structure you just have to change the \w+\d+ part of the regex.
Here's the result of this code:
bla(),($(ele).attr("data")),("test")
And if you like to know more about regex in javascript:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
Repeatedly strip out innermost parenthesized expressions:
var str = 'bla().func1($(ele).attr("data")).func2.func3("test")... ';
var expression = /\([^(]*?\)/g;
while (expression.test(str)) { str = str.replace(expression, ''); }
document.write(str.split('.').slice(1).join(' '));
However, you shouldn't do this (why do you want to?). JS should be parsed by, well, JS parsers. For instance, the above will fail miserably if there's a string literal containing a parenthesis. You should parse this using Esprima and analyze the resulting parse tree.

Javascript string validation using the regex object

I am complete novice at regex and Javascript. I have the following problem: need to check into a textfield the existence of one (1) or many (n) consecutive * (asterisk) character/characters eg. * or ** or *** or infinite (n) *. Strings allowed eg. *tomato or tomato* or **tomato or tomato** or as many(n)*tomato many(n)*. So, far I had tried the following:
var str = 'a string'
var value = encodeURIComponent(str);
var reg = /([^\s]\*)|(\*[^\s])/;
if (reg.test(value) == true ) {
alert ('Watch out your asterisks!!!')
}
By your question it's hard to decipher what you're after... But let me try:
Only allow asterisks at beginning or at end
If you only allow an arbitrary number (at least one) of asterisks either at the beginning or at the end (but not on both sides) like:
*****tomato
tomato******
but not **tomato*****
Then use this regular expression:
reg = /^(?:\*+[^*]+|[^*]+\*+)$/;
Match front and back number of asterisks
If you require that the number of asterisks at the biginning matches number of asterisks at the end like
*****tomato*****
*tomato*
but not **tomato*****
then use this regular expression:
reg = /^(\*+)[^*]+\1$/;
Results?
It's unclear from your question what the results should be when each of these regular expressions match? Are strings that test positive to above regular expressions fine or wrong is on you and your requirements. As long as you have correct regular expressions you're good to go and provide the functionality you require.
I've also written my regular expressions to just exclude asterisks within the string. If you also need to reject spaces or anything else simply adjust the [^...] parts of above expressions.
Note: both regular expressions are untested but should get you started to build the one you actually need and require in your code.
If I understand correctly you're looking for a pattern like this:
var pattern = /\**[^\s*]+\**/;
this won't match strings like ***** or ** ***, but will match ***d*** *d or all of your examples that you say are valid (***tomatos etc).If I misunderstood, let me know and I'll see what I can do to help. PS: we all started out as newbies at some point, nothing to be ashamed of, let alone apologize for :)
After the edit to your question I gather the use of an asterisk is required, either at the beginning or end of the input, but the string must also contain at least 1 other character, so I propose the following solution:
var pattern = /^\*+[^\s*]+|[^\s*]+\*+$/;
'****'.match(pattern);//false
' ***tomato**'.match(pattern);//true
If, however *tomato* is not allowed, you'll have to change the regex to:
var pattern = /^\*+[^\s*]+$|^[^\s*]+\*+$/;
Here's a handy site to help you find your way in the magical world of regular expressions.

Categories

Resources