Javascript Search for String Starting at End & Stopping at Another String - javascript

I have a string like this:
The planet is very big and the planet is heavy.
Using Javascript, I would like to search for a string starting from the end and stopping at another string.
An example would be, start at the word heavy, search for the word planet, but stop at the word big. The second instance of planet in this example is what I want, not the first. Therefore if there is not an instance of planet between big and heavy then I want to yield an indexOf -1.
Thanks.
Edit: I can accomplish this by splitting my string on the word I want than searching the second element of the array for my text but I was wondering if there was a function to do this.

You could split on the word "big" and then only lastIndexOf from the last subsstring group.
IE:
function foo(input,search,stopWord){
//Split the input
var arr=input.split(stopWord);
//return only from last substring group
return arr[arr.length-1].lastIndexOf(search);
}
foo("The planet is very big and the planet is heavy.","planet","big");
Does that give you the result you expect?

Run
var startIdx = string.lastIndexOf('big');
var grabIdx = string.lastIndexOf('planet');
(startIdx < grabIdx)?grabIdx: -1)

Related

Find and replace words between characters

I am working on this project, below is a replica of a string that I'm working on, but it is only for example purpose so it doesn't make much sense. My goal is to figure out the word between <ebm> and </ebm> and replace it accordingly.
var string = "“You know you're in love when <ebm>img-1</ebm> you can't fall asleep because reality <ebm>img-2</ebm>is finally better than your dreams.” <ebm>img-3</ebm>"
For example, if the word between <ebm> and </ebm> is
"img-1" then replace it with "Strong" (remove the <ebm> tags)
"img-2" then replace it with "Weak" (remove the <ebm> tags)
"img-3" then replace it with "Nice" (remove the <ebm> tags)
I cannot just simply use string.replace() because I have hundred lists of these words that has to be replaced accordingly. I need to know what's inside the word between tags so that I can use it to extract the approriate value on my array list.
Do a regex replacement with a callback function:
var terms = {};
terms['img-1'] = 'Strong';
terms['img-2'] = 'Weak';
terms['img-3'] = 'Nice';
var text = "“You know you're in love when <ebm>img-1</ebm> you can't fall asleep because reality <ebm>img-2</ebm>is finally better than your dreams.” <ebm>img-3</ebm>";
text = text.replace(/<ebm>(.+?)<\/ebm>/g, function(match, contents, offset, input_string)
{
return (terms[contents]);
});
console.log(text);
The idea here is to match every <ebm>...</ebm> tag, passing each match to a callback function. We then take the text captured in between the tags, and do a lookup in an associative array, which, for example, maps img-1 to Strong.

Javascript selecting to save one index of split()

I have a value - toggle-save_2
I want to extract the 2 part. The part after the underscore will always be what i need but the length of the former part, which in this case is toggle-save_, may vary (eg. notoggle-val_45). Though this length may vary it will always be separated from the end number by an underscore.
Right now I am using this
var current = this.id.split('_');
current = current[1];
to select the number.
What would be cool is if I could pass a variable to the split to only give me the second index of the result from the split.
Just select the 2nd index when you do the split.
var current = this.id.split('_')[1];
The best solution here would be to use lastIndexOf and substring, like this
function getLastPart(strObject) {
return strObject.substring(strObject.lastIndexOf("_") + 1);
}
console.log(getLastPart("toggle-save_2"));
// 2
console.log(getLastPart("notoggle-save_45"));
// 45
It is better for this case because, you already know that the _ will be somewhere near the last position. Since lastIndexOf starts from the last position, it would find _ very soon and all we need to do is to get the rest of the string from the next position.
There are often times I am breaking up a string where I only need the very last value of the result of String.prototype.split and consider the rest to be garbage no matter how many values the split produced.
When those cases arise, I like to chain Array.prototype.pop off of the split
var s = 'toggle-save_2',
current = s.split('_').pop();
The split method can only be limited from the end, and it will always return an array.
You don't need to use split, you can use string operations to get part of the string:
var current = this.id.substr(this.id.indexOf('_') + 1);

Find string using regular expression, and reuse said string with new surrounding text

I've searched Hi and low, but couldn't find an exact answer to what i'm trying to do...
I'd like to find any text with __ in the beginning and /__ at the end (i.e. "in the middle of the sentence __this/__ could be underlined, and __this(!) can also/__ be underlined"). so, it can be one word, or a few, with any characters in there, including spaces. There could be different words and combination - in the same paragraph - starting with __ and ending with /__ .
Once found, i'd like to remove the __ and /__ and replace them with HTML - for example, a div tag.
so:
__sample string /__
should be:
<div>sample string</div>
I know i'm supposed to use capturing groups, but i can't find a way to do this.
javascript:
.match seems to match, and put the results in an array - but how do i go back into the string and replace the found results?
jquery:
.replace should work for this, but i'm not sure how to reference the found string, and surround it...
Thanks for reading!
You don't need match but you need String#replace:
s='in the middle of the sentence __this/__ could be underlined, and __this(!) can also/__ be underlined';
var repl = s.replace(/__(.*?)\/__/g, "<div>$1</div>");
//=> in the middle of the sentence <div>this</div> could be underlined, and <div>this(!) can also</div> be underlined
Try this. It's a slight variation of something we have working here. I modified the replace part...but didn't actually test it. If you need to find more than one occurrence, I suppose you could pass-in a new starting index which would be the index of where you left off from the first time.
public static string getBetween(string strSource, string strStart, string strEnd)
{
int Start, End;
if (strSource.Contains(strStart) && strSource.Contains(strEnd))
{
Start = strSource.IndexOf(strStart, 0) + strStart.Length;
End = strSource.IndexOf(strEnd, Start);
return strSource.Substring(Start, End - Start);
}
else
{
return "";
}
}
string betweenString = getBetween(sourceString, "__", "/__");
sourceString = sourceString.Replace("__"+betweenString+"/__", "<div>"+betweenString+"</div>");

Cutting strings

I'm following the excersises in the book Eloquent Javascript and came up to this piece of code:
function between(string, start, end)
{
// Start AT the last character position of the start string
var startAt = string.indexOf(start) + start.length;
//Count the position of the end string first character
var endAt = string.indexOf(end, startAt);
return string.slice(startAt, endAt);
}
var betweenIn = between('Inazuma Eleven', 'Ina', 'ven');
console.log(betweenIn);
Code works fine. It extracts a piece of string between in. Now I tried to really understand this piece, but one thing isn't clear to me. The variable endAt checks the string's first character position of the third given parameter, (in this case my string is 'Inazuma Eleven' end the parameter is 'ven'. I need that for slicing the string, BUT it seems that the second parameter of the indexOf method doesn't do anything. If I remove it, I get the same results. Why is this?
The second parameter of indexOf defaults to 0. This is the place in the string where it will start looking for your matching substring.
Starting after the end of the start string ensures that a) your end string doesn't match the first instance of it if the start string and end string are identical, and b) you have to scan less of the target string so the code runs faster.
In this instance, your start and end strings are different, so the outcome is the same. However since the indexOf method will be searching more of the string (starting from 0 instead of the 4th character) it will run fractionally slower.

JavaScript regex back references returning an array of matches from single capture group (multiple groups)

I'm fairly sure after spending the night trying to find an answer that this isn't possible, and I've developed a work around - but, if someone knows of a better method, I would love to hear it...
I've gone through a lot of iterations on the code, and the following is just a line of thought really. At some point I was using the global flag, I believe, in order for match() to work, and I can't remember if it was necessary now or not.
var str = "#abc#def#ghi&jkl";
var regex = /^(?:#([a-z]+))?(?:&([a-z]+))?$/;
The idea here, in this simplified code, is the optional group 1, of which there is an unspecified amount, will match #abc, #def and #ghi. It will only capture the alpha characters of which there will be one or more. Group 2 is the same, except matches on & symbol. It should also be anchored to the start and end of the string.
I want to be able to back reference all matches of both groups, ie:
result = str.match(regex);
alert(result[1]); //abc,def,ghi
alert(result[1][0]); //abc
alert(result[1][1]); //def
alert(result[1][2]); //ghi
alert(result[2]); //jkl
My mate says this works fine for him in .net, unfortunately I simply can't get it to work - only the last matched of any group is returned in the back reference, as can be seen in the following:
(additionally, making either group optional makes a mess, as does setting global flag)
var str = "#abc#def#ghi&jkl";
var regex = /(?:#([a-z]+))(?:&([a-z]+))/;
var result = str.match(regex);
alert(result[1]); //ghi
alert(result[1][0]); //g
alert(result[2]); //jkl
The following is the solution I arrived at, capturing the whole portion in question, and creating the array myself:
var str = "#abc#def#ghi&jkl";
var regex = /^([#a-z]+)?(?:&([a-z]+))?$/;
var result = regex.exec(str);
alert(result[1]); //#abc#def#ghi
alert(result[2]); //jkl
var result1 = result[1].toString();
result[1] = result1.split('#')
alert(result[1][1]); //abc
alert(result[1][2]); //def
alert(result[1][3]); //ghi
alert(result[2]); //jkl
That's simply not how .match() works in JavaScript. The returned array is an array of simple strings. There's no "nesting" of capture groups; you just count the ( symbols from left to right.
The first string (at index [0]) is always the overall matched string. Then come the capture groups, one string (or null) per array element.
You can, as you've done, rearrange the result array to your heart's content. It's just an array.
edit — oh, and the reason your result[1][0] was "g" is that array indexing notation applied to a string gets you the individual characters of the string.

Categories

Resources