Remove all the dots of the string outside the brackets - javascript

I have string
var string = .row-4 .col-2.grid-unit+.grid-unit+.grid-unit,.row-4 .col-3 .grid-unit .row-4 .grid-unit:nth-of-type(2n+3) .show-grid+.show-grid-reportdiv
and i need to remove all plus sign leaving the plus sign inside the brackets from the string using javascript

I'd go with something along those lines:
var i, splits, string = ".row-4 .col-2.grid-unit+.grid-unit+.grid-unit,.row-4 .col-3 .grid-unit .row-4 .grid-unit:nth-of-type(2n+3) .show-grid+.show-grid-reportdiv";
splits = string.split(/(\([^)]+\))/);
for (i = 0; i< splits.length; i++) {
if (splits[i].charAt(0) !== "(") {
splits[i] = splits[i].replace("+"," ");
}
}
string = splits.join();
Another way around (dunno if it's better performance wise) would be to use the following:
var string = ".row-4 .col-2.grid-unit+.grid-unit+.grid-unit,.row-4 .col-3 .grid-unit .row-4 .grid-unit:nth-of-type(2n+3) .show-grid+.show-grid-reportdiv";
function replacer (match, offset, string) {
var posOpen = string.indexOf("(",offset);
var posClose = string.indexOf(")",offset);
// we replace it if there are no more closing parenthesis or if there is one that is located after an opening one.
if (posClose === -1 || (posClose > posOpen && posOpen !== -1)) {
return " ";
} else {
return "+";
}
};
string.replace(/\+/g, replacer);
EDIT: added bergi suggestion for a quicker check inside the loop.
EDIT2: Second solution

Use the following code, and let me know if it works :)
var myString = ".row-4 .col-2.grid-unit+.grid-unit+.grid-unit,.row-4:nth-of-type(2n+3) .col-3 .grid-unit .row-4 .grid-unit:nth-of-type(2n+3) .show-grid+.show-grid-reportdiv";
var myArray = myString.split(/\(.[\(\)A-Za-z0-9-.+]*\)/);
for(var i = 0; i < myArray.length; i++) {
myString = myString.replace(myArray[i], myArray[i].replace(/[+]/g,' '));
}

Related

Escape less than and greater than in HTML

content = '5<x<div></div>'
Basically I am looking for a regular expression that will make the string like above into 5<x<div></div>
5x<div></div> will still be 5x<div></div>. I am just trying to escape unclosed html tags
If there is such a library then I will be very happy to use it as long as it meets my main goal of trying to escape unclosed html tags
Rewrite each open tag character "<" with the symbol + unique value ... in this case ",,#*&,,"
Split the string at the unique value
The "replaceString ()" function checks if the passed value is really a tag ... whether both "<" and ">" characters are present in the string. If not present, rewrite the character with "& lt;".
The whole process is repeated for the symbol ">"
This is not the most beautiful solution to this task but it works.
var str = '5<x<div>s>7</div>';
for (var i = 0; i < 2; i++) {
if (i === 0) {
var str2 = str.replace(/</gi, ",,#*&,,<");
var spl = str2.split(",,#*&,,");
} else {
var str2 = str.replace(/>/gi, ">,,#*&,,");
var spl = str2.split(",,#*&,,");
}
replaceString(spl);
}
function replaceString(spl) {
for (let i = 0; i < spl.length; i++) {
if (spl[i].indexOf('<') > -1 && spl[i].indexOf('>') > -1) {
//.......
} else {
if (spl[i].indexOf('<') > -1) {
spl[i] = spl[i].replace(/</gi, "<");
}
else if (spl[i].indexOf('>') > -1) {
spl[i] = spl[i].replace(/>/gi, ">");
}
}
}
str = spl.join('');
}
console.log(str);

How to alternate the case of a string

I'm working on alternating the case of a string (for example asdfghjkl to AsDfGhJkL).
I tried to do this. I found some code that is supposed to do it, but it doesn't seem to be working.
var str="";
var txt=document.getElementById('input').value;
for (var i=0; i<txt.length; i+2){
str = str.concat(String.fromCharCode(txt.charCodeAt(i).toUpperCase()));
}
Here's a quick function to do it. It makes the entire string lowercase and then iterates through the string with a step of 2 to make every other character uppercase.
var alternateCase = function (s) {
var chars = s.toLowerCase().split("");
for (var i = 0; i < chars.length; i += 2) {
chars[i] = chars[i].toUpperCase();
}
return chars.join("");
};
var txt = "hello world";
console.log(alternateCase(txt));
HeLlO WoRlD
The reason it converts the string to an array is to make the individual characters easier to manipulate (i.e. no need for String.prototype.concat()).
Here an ES6 approach:
function swapCase(text) {
return text.split('').map((c,i) =>
i % 2 == 0 ? c.toLowerCase() : c.toUpperCase()
).join('');
}
console.log(swapCase("test"))
You should iterate the string and alternate between upper-casing the character and lower-casing it:
for (var i=0; i<txt.length; i++) {
var ch = String.fromCharCode(txt.charCodeAt(i);
if (i % 2 == 1) {
ch = ch.toUpperCase();
} else {
ch = ch.toLowerCase();
}
str = str.concat(ch);
}

Javascript: Split a string by comma, except inside parentheses

Given string in the form:
'"abc",ab(),c(d(),e()),f(g(),zyx),h(123)'
How can I split it to get the below array format:
abc
ab()
c(d(),e())
f(g(),zyx)
h(123)
I have tried normal javascript split, however it doesn't work as desired. Trying Regular Expression but not yet successful.
You can keep track of the parentheses, and add those expressions when the left and right parens equalize.
For example-
function splitNoParen(s){
var left= 0, right= 0, A= [],
M= s.match(/([^()]+)|([()])/g), L= M.length, next, str= '';
for(var i= 0; i<L; i++){
next= M[i];
if(next=== '(')++left;
else if(next=== ')')++right;
if(left!== 0){
str+= next;
if(left=== right){
A[A.length-1]+=str;
left= right= 0;
str= '';
}
}
else A=A.concat(next.match(/([^,]+)/g));
}
return A;
}
var s1= '"abc",ab(),c(d(),e()),f(g(),zyx),h(123)';
splitNoParen(s1).join('\n');
/* returned value: (String)
"abc"
ab()
c(d(),e())
f(g(),zyx)
h(123)
*/
This might be not the best or more refined solution, and also maybe won't fit every single possibility, but based on your example it works:
var data = '"abc",ab(),c(d(),e()),f(g(),zyx),h(123)';
// Create a preResult splitting the commas.
var preResult = data.replace(/"/g, '').split(',');
// Create an empty result.
var result = [];
for (var i = 0; i < preResult.length; i++) {
// Check on every preResult if the number of parentheses match.
// Opening ones...
var opening = preResult[i].match(/\(/g) || 0;
// Closing ones...
var closing = preResult[i].match(/\)/g) || 0;
if (opening != 0 &&
closing != 0 &&
opening.length != closing.length) {
// If the current item contains a different number of opening
// and closing parentheses, merge it with the next adding a
// comma in between.
result.push(preResult[i] + ',' + preResult[i + 1]);
i++;
} else {
// Leave it as it is.
result.push(preResult[i]);
}
}
Demo
For future reference, here's another approach to top-level splitting, using string.replace as a control flow operator:
function psplit(s) {
var depth = 0, seg = 0, rv = [];
s.replace(/[^(),]*([)]*)([(]*)(,)?/g,
function (m, cls, opn, com, off, s) {
depth += opn.length - cls.length;
var newseg = off + m.length;
if (!depth && com) {
rv.push(s.substring(seg, newseg - 1));
seg = newseg;
}
return m;
});
rv.push(s.substring(seg));
return rv;
}
console.log(psplit('abc,ab(),c(d(),e()),f(g(),zyx),h(123)'))
["abc", "ab()", "c(d(),e())", "f(g(),zyx)", "h(123)"]
Getting it to handle quotes as well would not be too complicated, but at some point you need to decide to use a real parser such as jison, and I suspect that would be the point. In any event, there's not enough detail in the question to know what the desired handling of double quotes is.
You can't use .split for this, but instead you'll have to write a small parser like this:
function splitNoParen(s){
let results = [];
let next;
let str = '';
let left = 0, right = 0;
function keepResult() {
results.push(str);
str = '';
}
for(var i = 0; i<s.length; i++) {
switch(s[i]) {
case ',':
if((left === right)) {
keepResult();
left = right = 0;
} else {
str += s[i];
}
break;
case '(':
left++;
str += s[i];
break;
case ')':
right++;
str += s[i];
break;
default:
str += s[i];
}
}
keepResult();
return results;
}
var s1= '"abc",ab(),c(d(),e()),f(g(),zyx),h(123)';
console.log(splitNoParen(s1).join('\n'));
var s2='cats,(my-foo)-bar,baz';
console.log(splitNoParen(s2).join('\n'));
Had a similar issue and existing solutions were hard to generalize. So here's another parser that's a bit more readable and easier to extend to your personal needs. It'll also work with curly braces, brackets, normal braces, and strings of any type. License is MIT.
/**
* This function takes an input string and splits it by the given token, but only if the token is not inside
* braces of any kind, or a string.
* #param {string} input The string to split.
* #param {string} split_by Must be a single character.
* #returns {string[]} An array of split parts without the split_by character.
*/
export function parse_split(input:string, split_by:string = ",") : string[]
{
// Javascript has 3 types of strings
const STRING_TYPES = ["'","`","\""] as const;
// Some symbols can be nested, like braces, and must be counted
const state = {"{":0,"[":0,"(":0};
// Some cannot be nested, like a string, and just flip a flag.
// Additionally, once the string flag has been flipped, it can only be unflipped
// by the same token.
let string_state : (typeof STRING_TYPES)[number] | undefined = undefined
// Nestable symbols come in sets, usually in pairs.
// These sets increase or decrease the state, depending on the symbol.
const pairs : Record<string,[keyof typeof state,number]> = {
"{":["{",1],
"}":["{",-1],
"[":["[",1],
"]":["[",-1],
"(":["(",1],
")":["(",-1]
}
let start = 0;
let results = [];
let length = input.length;
for(let i = 0; i < length; ++i)
{
let char = input[i];
// Backslash escapes the next character. We directly skip 2 characters by incrementing i one extra time.
if(char === "\\")
{
i++;
continue;
}
// If the symbol exists in the single/not nested state object, flip the corresponding state flag.
if(char == string_state)
{
string_state = undefined;
console.log("Closed string ", string_state);
}
// if it's not in a string, but it's a string opener, remember the string type in string_state.
else if(string_state === undefined && STRING_TYPES.includes(char as typeof STRING_TYPES[number]))
{
string_state = char as typeof STRING_TYPES[number];
}
// If it's not in a string, and if it's a paired symbol, increase or decrease the state based on our "pairs" constant.
else if(string_state === undefined && (char in pairs) )
{
let [key,value] = pairs[char];
state[key] += value;
}
// If it's our split symbol...
else if(char === split_by)
{
// ... check whether any flags are active ...
if(Object.entries(state).every(([k,v])=>v == 0) && (string_state === undefined))
{
// ... if not, then this is a valid split.
results.push(input.substring(start,i))
start = i+1;
}
}
}
// Add the last segment if the string didn't end in the split_by symbol, otherwise add an empty string
if(start < input.length)
{
results.push(input.substring(start,input.length))
}
else
results.push("");
return results;
}
With this regex, it makes the job:
const regex = /,(?![^(]*\))/g;
const str = '"abc",ab(),c(d(),e()),f(g(),zyx),h(123)';
const result = str.split(regex);
console.log(result);
Javascript
var str='"abc",ab(),c(d(),e()),f(g(),zyx),h(123)'
str.split('"').toString().split(',').filter(Boolean);
this should work

Replacing commas with dot and dot with commas

I am trying to replace all dots for comma and commas for dots and was wondering what is the best practice for doing this. If I do it sequentially, then the steps will overwrite each other.
For example:
1,234.56 (after replacing commas) --> 1.234.56 (after replacing dots) --> 1,234,56
Which is obviously not what I want.
One option I guess is splitting on the characters and joining afterwards using the opposite character. Is there an easier/better way to do this?
You could use a callback
"1,234.56".replace(/[.,]/g, function(x) {
return x == ',' ? '.' : ',';
});
FIDDLE
If you're going to replace more than two characters, you could create a convenience function using a map to do the replacements
function swap(str, swaps) {
var reg = new RegExp('['+Object.keys(swaps).join('')+']','g');
return str.replace(reg, function(x) { return swaps[x] });
}
var map = {
'.':',',
',':'.'
}
var result = swap("1,234.56", map); // 1.234,56
FIDDLE
You could do the following:
var str = '1,234.56';
var map = {',':'.','.':','};
str = str.replace(/[,.]/g, function(k) {
return map[k];
});
Working Demo
Do it in stages using placeholder text:
var foo = '1,234.56';
foo = foo
.replace(',', '~comma~')
.replace('.', '~dot~')
.replace('~comma~', '.')
.replace('~dot~', ',')
You could use a for loop. Something like:
var txt = document.getElementById("txt");
var newStr = "";
for (var i = 0; i < txt.innerHTML.length; i++){
var char = txt.innerHTML.charAt(i);
if (char == "."){
char = ",";
}else if (char == ","){
char = ".";
}
newStr += char;
}
txt.innerHTML = newStr;
Here's a fiddle:
http://jsfiddle.net/AyLQt/1/
Have to say though, #adenoeo's answer is way more slick :D
In javascript you can use
var value = '1.000.000,55';
var splitValue = value.split('.');
for (var i = 0; i < splitValue.length; i++) {
var valPart = splitValue[i];
var newValPart = valPart.replace(',', '.');
splitValue[i] = newValPart;
}
var newValue = splitValue.join(',');
console.log(newValue);

Remove comma from javascript array

Hi all I am framing a url with Query string in javascript as follows every thing works fine but a comm is coming in between the query string so can some one help me
<script type="text/javascript">
function RedirectLocation() {
var cntrl = "Q1;Q2";
var str_array = cntrl.split(';');
var cnt = str_array.length;
if (cnt == 0) {
location.href = '/callBack.aspx';
}
else {
var arr = [];
for (var i = 0; i < str_array.length; i++) {
str_array[i] = str_array[i].replace(/^\s*/, "").replace(/\s*$/, "");
arr.push(str_array[i] + '=1');
if (i != str_array.length - 1) {
arr.push('&');
}
}
location.href = '/Sample.aspx?' + arr;
}
}
</script>
This is giving me the query string as follows Sample.aspx?Q1=1,&,Q2=1 I need this to be like `Sample.aspx?Q1=1&Q2=1
To remove the commas from a string you could simply do
s = s.replace(/,/g,'');
But in your specific case, what you want is not to add the commas. Change
location.href = '/Sample.aspx?' + arr;
to
location.href = '/Sample.aspx?' + arr.join('');
What happens is that adding an array to a string calls toString on that array and that function adds the commas :
""+["a","b"] gives "a,b"
Don't rely on the implicit string conversion (which concatenates the array elements with a comma as separator), explicitly .join the array elements with &:
var arr = [];
for (var i = 0; i < str_array.length; i++) {
str_array[i] = str_array[i].replace(/^\s*/, "").replace(/\s*$/, "");
arr.push(str_array[i] + '=1');
}
location.href = '/Sample.aspx?' + arr.join('&');
Think about it like this: You have a set of name=value entries which you want to have separated by &.
You can use arr.join(glue) to concatenate Array elements with something inbetween. In your case glue would be an empty string arr.join("").

Categories