jQuery - find and replace substring - javascript

Let's say I got strings like this
'Hello, I am ***Groot*** today.'
'This is ***not*** my final form.'
'Test test ***123***'
and I want to add some new stuff before the first and after the second asterix to make it look like
'Hello, I am FIRST***Groot***LAST today.'
'This is FIRST***not***LAST my final form.'
'Test test FIRST***123***LAST'
So far I managed to get this
var first = jQuery(this).html().indexOf("***");
var last = jQuery(this).html().lastIndexOf("***");
console.log( jQuery(this).html().substring(first, last+3) );
but I fail on the replacement...so close, yet so far....

You can use regex pretty easily... this will work for all of your strings.
JSFiddle (check js console)
var str = jQuery(this).text();
str = str.replace(/(\*{3}.*\*{3})/, "FIRST$1LAST");
console.log(str);
Also, you don't really need to create the jQuery objects just to get the text, could just do this:
var str = this.innerText;
str = str.replace(/\*{3}.*\*{3}/, "FIRST$&LAST");
console.log(str);

I believe the correct special replacement character in your replacement parameter should be $& rather than $1 just for readability sake and best practices.
$& corresponds to the matched substring, whereas $1 makes it seem like there are multiple matches in the RegExp object.
Reference here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

Related

In Javascript, I need a RegEx to remove text in a string between 2 texts (range) with multiple apperance

Let's say I have this string:
var str = 'abc abcd --from-- xyz xyzz --to-- abc abcdd --from-- xsfkj --to-- abc';
My method should remove all the text between --from-- and --to--.
I think the best way is to do it with RegEx, I just don't know how...
I looked into this solution but I got this string as a result:
console.log(str.replace(/--from--.*--to--/, "")); // result:"abc abcd abc", not good.
In addition, is it possible to set a parameter instead of hard coded text in the range borders?
Thanks.
You need global flag with lazy quantifier:
console.log(str.replace(/--from--.*?--to--/g, ""));
//=> abc abcd abc abcdd abc
Update:
You can use variables in regex like this:
var from = '--from--';
var to = '--to--';
var re = new RegExp(from + '.*?' + to, "g");
console.log(str.replace(re, ""));
You need to use a non greedy and put the replace part in a capture group or use look around :
str.replace(/--from--(.*?)--to--/g, "")
And if you want to replace --from-- and --to-- you don't need capture group anymore.
str.replace(/--from--.*?--to--/g, "")

javascript regexp match tag names

I can't remember the name of it, but I believe you can reference already matched strings within a RegExp object. What I want to do is match all tags within a given string eg
<ul><li>something in the list</li></ul>
the RegExp should be able to match only the same tags, then I will use a recursive function to put all the individual matches in an array. The regex that should work if I can reference the first match would be.
var reg = /(?:<(.*)>(.*)<(?:FIRST_MATCH)\/>)/g;
The matched array should then contain
match[0] = "<ul><li>something in the list</li></ul>";
match[1] = "ul";
match[2] = ""; // no text to match
match[3] = "li";
match[4] = "something in the list";
thanks for any help
It seems like you mean backreference (\1, \2):
var s = '<ul><li>something in the list</li></ul>';
s.match(/<([^>]+)><([^>]+)>(.*?)<\/\2><\/\1>/)
// => ["<ul><li>something in the list</li></ul>",
// "ul",
// "li",
// "something in the list"]
The result is not exactly same with what you want. But point is that the backreference \1, \2 match the string that was matched by earlier group.
It is not possible to parse HTML using regular expressions (if you're interested in the specifics, it is because HTML parsing requires a stronger type of automaton than a finite state automaton which is what a regular expression can express - look up FSA vs FST for more info).
You might be able to get away with some hack for a specific problem, but if you want to reliably parse HTML using Javascript then there are other ways to do this. Search the web for: parse html javascript and you'll get plenty of pointers on how to do this.
I made a dirty workaround. Still needs work thought.
var str = '<div><ul id="list"><li class="something">this is the text</li></ul></div>';
function parseHTMLFromString(str){
var structure = [];
var matches = [];
var reg = /(<(.+)(?:\s([^>]+))*>)(.*)<\/\2>/;
str.replace(reg, function(){
//console.log(arguments);
matches.push(arguments[4]);
structure.push(arguments[1], arguments[4]);
});
while(matches.length){
matches.shift().replace(reg, function(){
console.log(arguments);
structure.pop();
structure.push(arguments[1], arguments[4]);
matches.push(arguments[4]);
});
}
return structure;
}
// parseHTMLFromString(str); // ["<div>", "<ul id="list">", "<li class="something">", "this is the text"]

Need a regex that finds "string" but not "[string]"

I'm trying to build a regular expression that parses a string and skips things in brackets.
Something like
string = "A bc defg hi [hi] jkl mnop.";
The .match() should return "hi" but not [hi]. I've spent 5 hours running through RE's but I'm throwing in the towel.
Also this is for javascript or jquery if that matters.
Any help is appreciated. Also I'm working on getting my questions formatted correctly : )
EDIT:
Ok I just had a eureka moment and figured out that the original RegExp I was using actually did work. But when I was replaces the matches with the [matches] it simply replaced the first match in the string... over and over. I thought this was my regex refusing to skip the brackets but after much time of trying almost all of the solutions below, I realized that I was derping Hardcore.
When .replace was working its magic it was on the first match, so I quite simply added a space to the end of the result word as follows:
var result = string.match(regex);
var modifiedResult = '[' + result[0].toString() + ']';
string.replace(result[0].toString() + ' ', modifiedResult + ' ');
This got it to stop targeting the original word in the string and stop adding a new set of brackets to it with every match. Thank you all for your help. I am going to give answer credit to the post that prodded me in the right direction.
preprocess the target string by removing everything between brackets before trying to match your RE
string = "A bc defg hi [hi] jkl mnop."
tmpstring = string.replace(/\[.*\]/, "")
then apply your RE to tmpstring
correction: made the match for brackets eager per nhahtd comment below, and also, made the RE global
string = "A bc defg hi [hi] jkl mnop."
tmpstring = string.replace(/\[.*?\]/g, "")
You don't necessarily need regex for this. Simply use string manipulation:
var arr = string.split("[");
var final = arr[0] + arr[1].split("]")[1];
If there are multiple bracketed expressions, use a loop:
while (string.indexOf("[") != -1){
var arr = string.split("[");
string = arr[0] + arr.slice(1).join("[").split("]").slice(1).join("]");
}
Using only Regular Expressions, you can use:
hi(?!])
as an example.
Look here about negative lookahead: http://www.regular-expressions.info/lookaround.html
Unfortunately, javascript does not support negative lookbehind.
I used http://regexpal.com/ to test, abcd[hi]jkhilmnop as test data, hi(?!]) as the regex to find. It matched 'hi' without matching '[hi]'. Basically it matched the 'hi' so long as there was not a following ']' character.
This of course, can be expanded if needed. This has a benefit of not requiring any pre-processing for the string.
r"\[(.*)\]"
Just play arounds with this if you wanto to use regular expressions.
What do yo uwant to do with it? If you want to selectively replace parts like "hi" except when it's "[hi]", then I often use a system where I match what I want to avoid first and then what I want to watch; if it matches what I want to avoid then I return the match, otherwise I return the processed match.
Like this:
return string.replace(/(\[\w+\])|(\w+)/g, function(all, m1, m2) {return m1 || m2.toUpperCase()});
which, with the given string, returns:
"A BC DEFG HI [hi] JKL MNOP."
Thus: it replaces every word with uppercase (m1 is empty), except if the word is between square brackets (m1 is not empty).
This builds an array of all the strings contained in [ ]:
var regex = /\[([^\]]*)\]/;
var string = "A bc defg hi [hi] [jkl] mnop.";
var results=[], result;
while(result = regex.exec(string))
results.push(result[1]);
edit
To answer to the question, this regex returns the string less all is in [ ], and trim whitespaces:
"A bc defg [hi] mnop [jkl].".replace(/(\s{0,1})\[[^\]]*\](\s{0,1})/g,'$1')
Instead of skipping the match you can probably try something different - match everything but do not capture the string within square brackets (inclusive) with something like this:
var r = /(?:\[.*?[^\[\]]\])|(.)/g;
var result;
var str = [];
while((result = r.exec(s)) !== null){
if(result[1] !== undefined){ //true if [string] matched but not captured
str.push(result[1]);
}
}
console.log(str.join(''));
The last line will print parts of the string which do not match the [string] pattern. For example, when called with the input "A [bc] [defg] hi [hi] j[kl]u m[no]p." the code prints "A hi ju mp." with whitespaces intact.
You can try different things with this code e.g. replacing etc.

javascript - replace dash (hyphen) with a space

I have been looking for this for a while, and while I have found many responses for changing a space into a dash (hyphen), I haven't found any that go the other direction.
Initially I have:
var str = "This-is-a-news-item-";
I try to replace it with:
str.replace("-", ' ');
And simply display the result:
alert(str);
Right now, it doesn't do anything, so I'm not sure where to turn. I tried reversing some of the existing ones that replace the space with the dash, and that doesn't work either.
Thanks for the help.
This fixes it:
let str = "This-is-a-news-item-";
str = str.replace(/-/g, ' ');
alert(str);
There were two problems with your code:
First, String.replace() doesn’t change the string itself, it returns a changed string.
Second, if you pass a string to the replace function, it will only replace the first instance it encounters. That’s why I passed a regular expression with the g flag, for 'global', so that all instances will be replaced.
replace() returns an new string, and the original string is not modified. You need to do
str = str.replace(/-/g, ' ');
I think the problem you are facing is almost this: -
str = str.replace("-", ' ');
You need to re-assign the result of the replacement to str, to see the reflected change.
From MSDN Javascript reference: -
The result of the replace method is a copy of stringObj after the
specified replacements have been made.
To replace all the -, you would need to use /g modifier with a regex parameter: -
str = str.replace(/-/g, ' ');
var str = "This-is-a-news-item-";
while (str.contains("-")) {
str = str.replace("-", ' ');
}
alert(str);
I found that one use of str.replace() would only replace the first hyphen, so I looped thru while the input string still contained any hyphens, and replaced them all.
http://jsfiddle.net/LGCYF/
In addition to the answers already given you probably want to replace all the occurrences. To do this you will need a regular expression as follows :
str = str.replace(/-/g, ' '); // Replace all '-' with ' '
Use replaceAll() in combo with trim() may meet your needs.
const str = '-This-is-a-news-item-';
console.log(str.replaceAll('-', ' ').trim());
Imagine you end up with double dashes, and want to replace them with a single character and not doubles of the replace character. You can just use array split and array filter and array join.
var str = "This-is---a--news-----item----";
Then to replace all dashes with single spaces, you could do this:
var newStr = str.split('-').filter(function(item) {
item = item ? item.replace(/-/g, ''): item
return item;
}).join(' ');
Now if the string contains double dashes, like '----' then array split will produce an element with 3 dashes in it (because it split on the first dash). So by using this line:
item = item ? item.replace(/-/g, ''): item
The filter method removes those extra dashes so the element will be ignored on the filter iteration. The above line also accounts for if item is already an empty element so it doesn't crash on item.replace.
Then when your string join runs on the filtered elements, you end up with this output:
"This is a news item"
Now if you were using something like knockout.js where you can have computer observables. You could create a computed observable to always calculate "newStr" when "str" changes so you'd always have a version of the string with no dashes even if you change the value of the original input string. Basically they are bound together. I'm sure other JS frameworks can do similar things.
if its array like
arr = ["This-is-one","This-is-two","This-is-three"];
arr.forEach((sing,index) => {
arr[index] = sing.split("-").join(" ")
});
Output will be
['This is one', 'This is two', 'This is three']

Modifying a string by replacing

How can I replace some words in a string with some other words? For example:
var text1 = "This is a sentence. It is a pencil."
text2 = modify(text1);
I want text2 to be "That was a sentence. I was a pencil."
So modify function replaces This->That , is->was
To replace all instances of the substring is with was you can use the replace[MDN] method:
text2 = text1.replace(/is/g, "was");
Note that because is is a part of the word this, it will actually return
Thwas was a sentence
If you wanted to replace all instances of This to That and is to was, you could chain the calls to the replace method.
text2 = text1.replace(/This/g, "That").replace(/is/g, "was");
This will correctly do your replacement from
This is a sentence. It is a pencil.
to
That was a sentence. It was a pencil.
You can see this in action on jsFiddle.
Note that find and replace actions like this can always have unintended consequences. For example, this string
Thistles and thorns are bad for missiles and corns.
will turn into this one after your replacement:
Thatles and thorns are bad for mwassiles and corns.
This sort of thing is popularly known as the Clbuttic mistake.
text1 = text1.replace('is', 'was');
Btw, .replace accepts regular expressions as well
Utilize the javascript replace method -
http://www.w3schools.com/jsref/jsref_replace.asp
Note: To replace every occurrence of a string in JavaScript, you must provide the replace() method a regular expression with a global modifier as the first parameter.
You could use javascript's Replace function like this:
var text2 = text1.replace('is','was');

Categories

Resources