How to replace semicolon except when encountering data uri specific text? - javascript

I am replacing all semicolons with line breaks but I have to make a few exceptions.
results = results.replace(/;/g, "\n");
But now I have 3 cases where I do not want to replace the semicolon:
data:image/png;
data:image/jpeg;
data:image/gif;
Basically any thing:
data:image/*;
I have tried:
results = results.replace(/^(data:image/png;)|;/g, "\n");
But it doesn't work.
This kind of works but it replaces the semicolon and one preceding character:
results = results.replace(/[^(data:image/png;)];/g, "\n");
Test data:
borderradius:10;borderradius:20;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQUAAAGQCAYAAACnPXVhAAAz9ElEQVR4Ae2d2a8VxdqH+QO44YaECxISQ0IICSGEEAghEoKBQEEbfXUX7JizwEBUFBUJAGPA0IChKEJwh59uR59rjrLIACO/pTGUgD0gAa+D+0cw+oAw0jjQAAAABJRU5ErkJggg==);

The [^(data:image/png;)]; contains a common user error: a character class (single character matching pattern) is used where a grouping construct (sequence
matching pattern) is meant to be used. See Regex expression not working with once or none for a similar issue.
You may use a regex capturing the data:image/[something]; and then use a callback to decide whether to keep the capture or replace the ; with a linebreak:
var s = "data:image/png; data/png; text";
var res = s.replace(/\b(data:image\/[^\/;]*;)|;/g, function (_, $1) {
return $1 ? $1 : "\n";
});
document.body.innerHTML = "<pre>" + res + "</pre>";
The /\b(data:image\/[^\/;]*;)|;/g will match multiple occurrences of:
\b(data:image\/[^\/;]*;) - Group 1 capturing a whole word data:image followed with /, then with zero or more characters other than / and ; up to the first ;
| - or..
; - a literal semicolon (just matched, no capturing group is used here)
In the callback, if $1 is set (not null), we restore the captured text with $1, and if not, we just replace with \n since we matched a "stray" ;.

Related

Replace all spaces except the first & last ones

I want to replace all whitespaces except the first and the last one as this image.
How to replace only the red ones?
how to replace the red space
I tried :
.replace(/\s/g, "_");
but it captures all spaces.
I suggest match and capture the initial/trailing whitespaces that will be kept and then matching any other whitespace that will be replaced with _:
var s = " One Two There ";
console.log(
s.replace(/(^\s+|\s+$)|\s/g, function($0,$1) {
return $1 ? $1 : '_';
})
);
Here,
(^\s+|\s+$) - Group 1: either one or more whitespaces at the start or end of the string
| - or
\s - any other whitespace.
The $0 in the callback method represents the whole match, and $1 is the argument holding the contents of Group 1. Once $1 matches, we return its contents, else, replace with _.
You can use ^ to check for first character and $ for last, in other words, search for space that is either preceded by something other than start of line, or followed by something thing other than end of line:
var rgx = /(?!^)(\s)(?!$)/g;
// (?!^) => not start of line
// (?!$) => not end of line
console.log(' One Two Three '.replace(rgx, "_"));

JavaScript RegExp all chracters except dynamic series

So, I'm working on an opensource project as a way to expand my knowledge of JavaScript, and created an utility that processes strings dynamically, and replaces specific occurrences with other strings.
An example of this would be the following:
jdhfkjhs${c1}kdfjh$%^%$S654sgdsjh${c20}SUYTDRF^%$&*#(Y
And assuming I select the character '#', the RegExp processes it to be:
########${c1}####################${c20}###############
The problem I am facing is my RegExp /[^\$\{c\d\}]/g is also matching any of the characters inside of the RegExp, so a string such as _,met$$$$$1234{}cccgg. will be returned as #####$$$$$1234{}ccc###
Is there a way I can catch such a dynamic group with JavaScript, or should I find an alternative way to achieve what I am doing?
For some context, the project code can be found here.
You may match the group and capture it to restore later, and just match any char (with . if no line breaks are expected or with [^] / [\s\S]):
var rx = /(\${c\d+})|./g;
var str = 'jdhfkjhs\${c1}kdfjh\$%^%\$S654sgdsjh\${c20}SUYTDRF^%\$&*#(Y';
var result = str.replace(rx, function ($0,$1) {
return $1 ? $1 : '#';
});
console.log(result);
Details:
(\${c\d+}) - Group 1: a literal ${c substring, then 1+ digits and a literal }
| - or
. - any char but a line break char (or any char if you use [^] or [\s\S]).
In the replacement, $0 stands for the whole match, $1 stands for the contents of the first capturing group. If the $1 is set, it is re-inserted to the resulting string, else, the char is replaced with #.

Replace multiple characters by one character with regex

I have this string :
var str = '#this #is____#a test###__'
I want to replace all the character (#,_) by (#) , so the excepted output is :
'#this #is#a test#'
Note :
I did not knew How much sequence of (#) or (_) in the string
what I try :
I try to write :
var str = '#this #is__ __#a test###__'
str = str.replace(/[#_]/g,'#')
alert(str)
But the output was :
#this #is## ###a test#####
my try online
I try to use the (*) for sequence But did not work :
var str = '#this #is__ __#a test###__'
str = str.replace(/[#_]*/g,'#')
alert(str)
so How I can get my excepted output ?
A well written RegEx can handle your problem rather easily.
Quoting Mohit's answer to have a startpoint:
var str = '#this #is__ __#a test###__';
var formattedStr = str.replace(/[#_,]+/g, '#');
console.log( formattedStr );
Line 2:
Put in formattedStr the result of the replace method on str.
How does replace work? The first parameter is a string or a RegEx.
Note: RegExps in Javascripts are Objects of type RegExp, not strings. So writing
/yourRegex/
or
New RegExp('/yourRegex/')
is equivalent syntax.
Now let's discuss this particular RegEx itself.
The leading and trailing slashes are used to surround the pattern, and the g at the end means "globally" - do not stop after the first match.
The square parentheses describe a set of characters who can be supplied to match the pattern, while the + sign means "1 or more of this group".
Basically, ### will match, but also # or #####_# will, because _ and # belong to the same set.
A preferred behavior would be given by using (#|_)+
This means "# or _, then, once found one, keep looking forward for more or the chosen pattern".
So ___ would match, as well as #### would, but __## would be 2 distinct match groups (the former being __, the latter ##).
Another problem is not knowing wheter to replace the pattern found with a _ or a #.
Luckily, using parentheses allows us to use a thing called capturing groups. You basically can store any pattern you found in temporary variabiles, that can be used in the replace pattern.
Invoking them is easy, propend $ to the position of the matched (pattern).
/(foo)textnotgetting(bar)captured(baz)/ for example would fill the capturing groups "variables" this way:
$1 = foo
$2 = bar
$3 = baz
In our case, we want to replace 1+ characters with the first occurrence only, and the + sign is not included in the parentheses!
So we can simply
str.replace("/(#|_)+/g", "$1");
In order to make it work.
Have a nice day!
Your regex replaces single instance of any matched character with character that you specified i.e. #. You need to add modifier + to tell it that any number of consecutive matching characters (_,#) should be replaced instead of each character individually. + modifier means that 1 or more occurrences of specified pattern is matched in one go. You can read more about modifiers from this page:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
var str = '#this #is__ __#a test###__';
var formattedStr = str.replace(/[#_,]+/g, '#');
console.log( formattedStr );
You should use the + to match one-or-more occurrences of the previous group.
var str = '#this #is__ __#a test###__'
str = str.replace(/[#_]+/g,'#')
alert(str)

Escape single backslash inbetween non-backslash characters only

I have some input coming in a web page which I will re display and submit elsewhere. The current issue is that I want to double up all single backslashes that are sandwiched inbetween non-backslash characters before submitting the input elsewhere.
Test string "domain\name\\nonSingle\\\WontBe\\\\Returned", I want to only get the first single backslash, between domain and name.
This string should get nothing "\\get\\\nothing\\\\"
My current pattern that I can get closest with is [\w][\\](?!\\) however this will get the "\n" from the 1st test string i have listed. I would like to use lookbehind for the regex however javascript does not have such a thing for the version I am using. Here is the site I have been testing my regexs on http://www.regexpal.com/
Currently I am inefficiently using this regex [\w][\\](?!\\) to extract out all single backslashes sandwiched between non-backslash characters and the character before them (which I don't want) and then replacing it with the same string plus a backslash at the end of it.
For example given domain\name\\bl\\\ah my current regex [\w][\\]\(?!\\) will return "n\". This results in my code having to do some additional processing rather than just using replace.
I don't care about any double, triple or quadruple backslashes present, they can be left alone.
For example given domain\name\\bl\\\ah my current regex [\w][\\]\(?!\\) will return "n\". This results in my code having to do some additional processing rather than just using replace.
It will do just using replace, since you can insert the matched substring with $&, see:
console.log(String.raw`domain\name\\bl\\\ah`.replace(/\w\\(?!\\)/g, "$&\\"))
Easiest method of matching escapes, is to match all escaped characters.
\\(.)
And then in the replacement, decide what to do with it based on what was captured.
var s = "domain\\name\\\\backslashesInDoubleBackslashesWontBeReturned";
console.log('input:', s);
var r = s.replace(/\\(.)/g, function (match, capture1) {
return capture1 === '\\' ? match : '$' + capture1;
});
console.log('result:', r);
The closest you can get to actually matching the unescaped backslashes is
((?:^|[^\\])(?:\\\\)*)\\(?!\\)
It will match an odd number of backslashes, and capture all but the last one into capture group 1.
var re = /((?:^|[^\\])(?:\\\\)*)\\(?!\\)/g;
var s = "domain\\name\\\\escapedBackslashes\\\\\\test";
var parts = s.split(re);
console.dir(parts);
var cleaned = [];
for (var i = 1; i < parts.length; i += 2)
{
cleaned.push(parts[i-1] + parts[i]);
}
cleaned.push(parts[parts.length - 1]);
console.dir(cleaned);
The even-numbered (counting from zero) items will be unmatched text. The odd-numbered items will be the captured text.
Each captured text should be considered part of the preceding text.

Regular expression in JavaScript that matches ${}

I want regular expressions to match string that starts with either ${ , "${ , '${ and ends with } , }' , }". My string may be ${anythinghere}, "${anythinghere}", '${anythinghere}'. I tried with the following
var str = "${a}";
var patt = /^("|'|${)*(}|'|")$/;
var res = patt.test(str);
alert(res);
But my above code always returns false.
You have to escape the inner $ with a backslash, since it's a special character. But that alone won't fix the problem. As it is above, patt matches any string that begins with " or ' or ${, 0 or more times, and ends with } or ' or ". The regular expression that you want would be something like this:
var str = "${a}";
var patt = /^(['"]?)\${.*}\1$/;
var res = patt.test(str);
alert(res);
Here is what each part of patt is doing:
^(['"]?): The string must begin with 0 or 1 single quote, or with 0 or 1 double quote. This is in parentheses so that we can reference it at the end of the regexp
\${: Next must be a dollar sign followed by an open curly bracket
.*: Next must be 0 or more of any character (other than a newline)
}: Next must be a closed curly bracket
\1$: Finally, the string must end with whatever pattern was matched at the beginning of the string. \1 is a "back-reference" to the first capturing group (in the parentheses), so if the string began with a single quote, it will only match if it also ends with a single quote. Same goes for double quotes, and no quotes at all
$ has a special meaning in regex, so it must be escaped using a backslash \. If you want 1 or more wildcards, that's represented with a .+, not a *. The following code will match the test pattern:
/^'?"?\${.+}'?"?$/
You can use
var a=new RegExp("\^(\'\\$\{)[a-z]+(\}\')|(\"\\$\{)[a-z]+(\}\")|(\\$\{)[a-z]+(\})\$");
a.test("${vijay}")//true
a.test("\'${vijay}\'")//true
a.test("\"${vijay}\"")//true
a.test("\'${vijay}\"")//false
If you use only \$ it takes as end og expresion.So use\\$ means $ as a special character
This works:
var str = "\"${a}\"";
var patt = /^\"\$\{((?!\").)+\}\"$/;
var res = patt.test(str);
alert(res);
Note that the value assigned to str has been changed to \"${a}\" in order to reflect what you stated targets. You must escape (put a backslash before) any character you wish to be read literally and not as a metacharacter. In order to have this match any one of your targets at once, simply repeat the pattern in patt three times, separated by pipes as usual, replacing the \" with \' or nothing at all (in which case, you should change the \" inside the inner most parenthesis to }). These changes are shown below:
var patt = /^\"\$\{((?!\").)+\}\"$|^\'\$\{((?!\').)+\}\'$|^\$\{((?!\}).)+\}$/;

Categories

Resources