how to replace a char in string with many chars - javascript

I want to change a char in string with many values
I have string like this :
date_format = "%m/%d/%Y";
And i want to replace ever % with the char which after, so the date variable should be like this:
date_format="mm/dd/YY";
Here is what I tried so far, but i can't get it to work, so I need some help here:
function replaceon(str, index, chr) {
if (index > str.length - 1) return str;
return str.substr(0, index) + chr + str.substr(index + 1);
}
function locations(substring, string) {
var a = [],
i = -1;
while ((i = string.indexOf(substring, i + 1)) >= 0) a.push(i);
return a;
}
function corrent_format(date_format) {
var my_locations = locations('%', date_format);
console.log(my_locations.length);
for (var i = 0; i < my_locations.length; i++) {
replaceon(date_format, my_locations[i], date_format[my_locations[i] + 1]);
}
return date_format;
}
console.log(corrent_format(date_format));

You can try this:
"%m/%d/%Y".replace(/%([^%])/g,"$1$1")
Hope this hepls.

You can use a regular expression for that:
var date_format="%m/%d/%Y";
var res = date_format.replace(/%(.)/g, "$1$1");
console.log(res);

function act(str) {
var res = "";
for (var i = 0; i < (str.length - 1); i++) {
if (str[i] === "%")
res += str[i + 1];
else
res += str[i];
}
res += str[i];
return res;
}
var date_format = "%m/%d/%Y";
console.log(act(date_format));

Your code is not working because the date_format variable is not being modified by the corrent_format function. The replaceon function returns a new string. If you assign the result to date_format, you should get the expected result:
for (var i = 0; i < my_locations.length; i++) {
date_format = replaceon(date_format, my_locations[i], date_format[my_locations[i]+1])
}
Alternatively, you could perform the replacement using String.replace and a regular expression:
date_format.replace(/%(.)/g, '$1$1');

For the regex-challenged among us, here's a translation of /%(.)/g, '$1$1':
/ means that the next part is going to be regex.
% find a %.
. any single character, so %. would match %m, %d, and/or %Y.
(.) putting it in parens means to capture the value to use later on.
/g get all the matches in the source string (instead of just the first one).
?1 references the value we captured before in (.).
?1?1 repeat the captured value twice.
So, replace every %. with whatever's in the ., times two.
Now, this regex expression is the most concise and quickest way to do the job at hand. But maybe you can't use regular expressions. Maybe you have a dyslexic boss who has outlawed their use. (Dyslexia and regex are uneasy companions at best.) Maybe you haven't put in the 47 hours screaming at regular expressions that aren't doing what you want, that you're required to put in before you're allowed to use them. Or maybe you just hate regular expressions.
If any of these apply, you can also do this:
var x = '%m/%d/%y';
x = x.replace('%', 'm');
x = x.replace('%', 'd');
x = x.replace('%', 'y');
alert(x);
This takes advantage of the fact that the replace function only replaces the first match found.
But seriously, don't use this. Use regex. It's always better to invest that 20 hours working out a regex expression that condenses the 20 lines of code you wrote in 15 minutes down to one. Unless you have to get it done sometime tonight, and whatever you're trying just doesn't work, and it's getting close to midnight, and you're getting tired...well, no. Use regex. Really. Resist the temptation to avoid finding a regex solution. You'll be glad you did when you wake up at your desk in the morning, having missed your deadline, and get to go home and spend more time with your family, courtesy of your generous severance package.

Related

How to find a particular char in string in my case "-" and replace it with "_" in javascript js

Hey guys i am currently learning javascript, i need to replace "-" with "_".
For example : "Hello-World" ==> "Hello_World" i tired the below code it didn't work,i want to know why this method is wrong,
function kS(n){
j=n.length;
for(i=0;i<j;i++){
if(n[i]=="-")
{
n[i]="_";
console.log(n);
}
}
}
Simply use replace
console.log("Hello-World".replace('-','_'))
You can just use String.replace to achieve that. If you use the regex input in combination with g modifier, it will match all occurences. https://regex101.com/ is a good place to test out such regexes.
var myString = "hello-word";
myString = myString.replace(/-/g, '_');
If you have to do it with a loop and are allowed to use ES2015 or newer, you could also write it like this:
var myString = "hello-word";
var newString = [...myString].map(c => c === '-' ? '_' : c).join('');
Stings are immutable. You could convert the string to an array of characters and check and replace the item in the characters array.
At the end return a joined array.
BTW, spelling matter, eg length and undeclared variables are global in Javascript, which should be avoided.
function kS([...characters]) {
var l = characters.length;
for (var i = 0; i < l; i++) {
if (characters[i] === "-") characters[i] = "_";
}
return characters.join('');
}
console.log(kS('1-2-3'));

Reshape String, inserting "\n" at every N characters

Using JavaScript functions, I was trying to insert a breakline on a string at every N characters provided by the user.
Just like this: function("blabla", 3) would output "bla\nbla\n".
I searched a lot of answers and ended up with a regex to do that, the only problem is, I need the user's input on the matter, so I need to stuck a variable on this regex.
Here's the code:
function reshapeString(string, num) {
var regex = new RegExp("/(.{" + num + "})/g");
return string.replace(regex,"$1\n");
}
reshapeString("blablabla", 3);
This is currently not working. I tried to escape the '/' characters, but I'm screwing up at some point and I don't know where.
What am I missing? Is there any other way to solve the problem of reshaping this string?
You need a string for the regexp constructor, without /, and you can omit the group by using $& for the found string.
function reshapeString(string, num) {
var regex = new RegExp(".{" + num + "}", "g");
return string.replace(regex,"$&\n");
}
console.log(reshapeString("blablabla", 3));
How about a one-liner?
const reshapeString = (str,N) => str.split('').reduce((o,c,i) => o+(!i || i%N?'':'\n')+c, '')
Explanation:
So first thing we do is split the string into a character array
Now we use a reduce() statement to go through each element and reduce to a single value (ie. the final string you're looking for!)
Now i%N should give a non-zero (ie. a truthy value) when the index is not a multiple of N, so we just add the current character to out accumulator variable o.
If i%N is in fact 0 (then it's falsey in value), and we append:
o (the string so far) +
\n (the appended character at the N'th interval)
c (the current character)
Note: We also have a !i check, that's for ignoring the first char since, that may be considered un-intended behavior
Benchmarking
Regex construction and replace also requires string re-construction and creating an FSA to follow. Which for strings smaller than 1000 should be slower
Test:
(_ => {
const reshapeString_AP = (str,N) => str.split('').reduce((o,c,i) => o+(!i || i%N?'':'\n')+c, '')
function reshapeString_Nina(string, num) {
var regex = new RegExp(".{" + num + "}", "g");
return string.replace(regex,"$&\n");
}
const payload = 'a'.repeat(100)
console.time('AP');
reshapeString_AP(payload, 4)
console.timeEnd('AP');
console.time('Nina');
reshapeString_Nina(payload, 4)
console.timeEnd('Nina');
})()
Results (3 runs):
AP: 0.080078125ms
Nina: 0.13916015625ms
---
AP: 0.057861328125ms
Nina: 0.119140625ms
---
AP: 0.070068359375ms
Nina: 0.116943359375ms
public static String reshape(int n, String str){
StringBuilder sb = new StringBuilder();
char[] c = str.replaceAll(" " , "").toCharArray();
int count =0;
for (int i = 0; i < c.length; i++) {
if(count != n){
sb.append(c[i]);
count++;
}else {
count = 1;
sb.append("\n").append(c[i]);
}
}
return sb.toString();
}
Strings are immutable so whatever you do you have to create a new string. It's best to start creating it in the first place.
var newLineForEach = (n,s) => s && `${s.slice(0,n)}\n${newLineForEach(n,s.slice(n))}`,
result = newLineForEach(3,"blablabla");
console.log(result);
So my tests show that this is by far the fastest. 100K iterations resulted Nina's 1260msec, AP's 103msec and Redu's 33msec. The accepted answer is very inefficient.

How to remove string between two characters every time they occur [duplicate]

This question already has answers here:
Strip HTML from Text JavaScript
(44 answers)
removing html tags from string
(3 answers)
Closed 7 years ago.
I need to get rid of any text inside < and >, including the two delimiters themselves.
So for example, from string
<brev-y>th</brev-y><sw-ex>a</sw-ex><sl>t</sl>​
I would like to get this one
that
This is what i've tried so far:
var str = annotation.split(' ');
str.substring(str.lastIndexOf("<") + 1, str.lastIndexOf(">"))
But it doesn't work for every < and >.
I'd rather not use RegEx if possible, but I'm happy to hear if it's the only option.
You can simply use the replace method with /<[^>]*>/g.It matches < followed by [^>]* any amount of non> until > globally.
var str = '<brev-y>th</brev-y><sw-ex>a</sw-ex><sl>t</sl>';
str = str.replace(/<[^>]*>/g, "");
alert(str);
For string removal you can use RegExp, it is ok.
"<brev-y>th</brev-y><sw-ex>a</sw-ex><sl>t</sl>​".replace(/<\/?[^>]+>/g, "")
Since the text you want is always after a > character, you could split it at that point, and then the first character in each String of the array would be the character you need. For example:
String[] strings = stringName.split("<");
String word = "";
for(int i = 0; i < strings.length; i++) {
word += strings[i].charAt(0);
}
This is probably glitchy right now, but I think this would work. You don't need to actually remove the text between the "<>"- just get the character right after a '>'
Using a regular expression is not the only option, but it's a pretty good option.
You can easily parse the string to remove the tags, for example by using a state machine where the < and > characters turns on and off a state of ignoring characters. There are other methods of course, some shorter, some more efficient, but they will all be a few lines of code, while a regular expression solution is just a single replace.
Example:
function removeHtml1(str) {
return str.replace(/<[^>]*>/g, '');
}
function removeHtml2(str) {
var result = '';
var ignore = false;
for (var i = 0; i < str.length; i++) {
var c = str.charAt(i);
switch (c) {
case '<': ignore = true; break;
case '>': ignore = false; break;
default: if (!ignore) result += c;
}
}
return result;
}
var s = "<brev-y>th</brev-y><sw-ex>a</sw-ex><sl>t</sl>";
console.log(removeHtml1(s));
console.log(removeHtml2(s));
There are several ways to do this. Some are better than others. I haven't done one lately for these two specific characters, so I took a minute and wrote some code that may work. I will describe how it works. Create a function with a loop that copies an incoming string, character by character, to an outgoing string. Make the function a string type so it will return your modified string. Create the loop to scan from incoming from string[0] and while less than string.length(). Within the loop, add an if statement. When the if statement sees a "<" character in the incoming string it stops copying, but continues to look at every character in the incoming string until it sees the ">" character. When the ">" is found, it starts copying again. It's that simple.
The following code may need some refinement, but it should get you started on the method described above. It's not the fastest and not the most elegant but the basic idea is there. This did compile, and it ran correctly, here, with no errors. In my test program it produced the correct output. However, you may need to test it further in the context of your program.
string filter_on_brackets(string str1)
{
string str2 = "";
int copy_flag = 1;
for (size_t i = 0 ; i < str1.length();i++)
{
if(str1[i] == '<')
{
copy_flag = 0;
}
if(str1[i] == '>')
{
copy_flag = 2;
}
if(copy_flag == 1)
{
str2 += str1[i];
}
if(copy_flag == 2)
{
copy_flag = 1;
}
}
return str2;
}

how to retrieve a string between to same charecter

I know how to use substring() but here I have a problem, I'd like to retrieve a number between two "_" from a unknown string length. here is my string for example.
7_28_li
and I want to get the 28. How can I proceed to do so ?
Thanks.
Regex
'7_28_li'.match(/_(\d+)_/)[1]
The slashes inside match make it's contents regex.
_s are taken literally
( and ) are for retrieving the contents (the target number) later
\d is a digit character
+ is "one or more".
The [1] on the end is accesses what got matched from the first set of parens, the one or more (+) digits (\d).
Loop
var str = '7_28_li';
var state = 0; //How many underscores have gone by
var num = '';
for (var i = 0; i < str.length; i++) {
if (str[i] == '_') state++;
else if (state == 1) num += str[i];
};
num = parseInt(num);
Probably more efficient, but kind of long and ugly.
Split
'7_28_li'.split('_')[1]
Split it into an array, then get the second element.
IndexOf
var str = "7_28_li";
var num = str.substring(str.indexOf('_') + 1, str.indexOf('_', 2));
Get the start and end point. Uses the little-known second parameter of indexOf. This works better than lastIndexOf because it is guaranteed to give the first number between _s, even when there are more than 2 underscores.
First find the index of _, and then find the next position of _. Then get the substring between them.
var data = "7_28_li";
var idx = data.indexOf("_");
console.log(data.substring(idx + 1, data.indexOf("_", idx + 1)));
# 28
You can understand that better, like this
var data = "7_28_li";
var first = data.indexOf("_");
var next = data.indexOf("_", first + 1);
console.log(data.substring(first + 1, next));
# 28
Note: The second argument to indexOf is to specify where to start looking from.
Probably the easiest way to do it is to call split on your string, with your delimiter ("_" in this case) as the argument. It'll return an array with 7, 28, and li as elements, so you can select the middle one.
"7_28_li".split("_")[1]
This will work if it'll always be 3 elements. If it's more, divide the length property by 2 and floor it to get the right element.
var splitstring = "7_28_li".split("_")
console.log(splitstring[Math.floor(splitstring.length/2)]);
I'm not sure how you want to handle even length strings, but all you have to do is set up an if statement and then do whatever you want.
If you know there would be 2 underscore, you can use this
var str = "7_28_li";
var res = str.substring(str.indexOf("_") +1, str.lastIndexOf("_"));
If you want to find the string between first 2 underscores
var str = "7_28_li";
var firstIndex = str.indexOf("_");
var secondIndex = str.indexOf("_", firstIndex+1);
var res = str.substring(firstIndex+1, secondIndex);

Algorithm (or regular expression) needed to find multiple instances of anything

I'm not sure if there is a simple way of doing this, but is there a way to find multiple instances in an unknown string? For example:
hellohellohellobyebyebyehello
Without knowing the value of the above string, can I return something that will tell me that there are 3 instances of "hello" and 3 instances of "bye" (I'm not worried about the last hello however as I'm looking for consecutive repetition. Thanks in advance!
Maybe the Sequitur algorithm can help: http://sequitur.info/
s = "hellohellohellobyebyebyehello"
s.replace(/(.+)(\1+)/g, function($0, $1) {
console.log($1 + " repeated " + ($0.length / $1.length) + " times");
});
"testhellohellohellobyebyebyehello".match(/(.+)\1+/)
This says : "match a sequence of at least 1 character (.+), then reference that first thing we found \1 at least one time + or more.
It will return ["hellohellohello", "hello"] meaning hellohellohello matches the full expression (expression 0), and "hello" matches expression 1 (the thing we reference with \1).
Caveat:
something like "hahahaha" will yield ["hahahaha", "haha"], instead of ["hahahaha", "ha"]. so you'll need to use the above with some post-processing to get to your desired result.
if you are looking up for dictionary words, you can load your lexicon in a suffix tree,
then consider the characters of your string one by one and go through your tree. Each time your reach a leaf you increment by one the associated "word".
var source = "asdhellohellohellobyehellohellohellohelloasdhello";
var key = "hello";
var len = key.length;
var res = 0, tempres, next;
var last = source.indexOf(key);
while(last != -1)
{
tempres = 0;
next = last;
while(true)
{
tempres++;
next += len;
last = source.indexOf(key, next);
if(last != next)
break;
}
res = (tempres > res) ? tempres : res;
}
console.log(res);//4

Categories

Resources