Reg Expression - In javascript how can I get the 2nd instance? - javascript

I have a string like:
some people may work for some thing new.
I need to fetch the 2nd instance of the word 'some' using javascript reg exp.
how can i get that?
here is my try:
var text = "some people may work for some thing new";
var patt = /some/.test(text);
console.log(patt);
But I am getting simply 'true' in console. But I need to get the word to be consoled. ( even i may need to replace too).
any one help me?

You need to use .match with the regex, and also use the g flag for global
var text = "some people may work for some thing new";
var patt = /some/g;
var matches = text.match(patt);
console.log( matches );
console.log( matches[1] );
Will give you an array of all instances of the word some

var text = "some people may work for some thing new";
var patt = text.match(/some/g);
console.log(patt);
will give you all the instances of the word you want to find in the sentence.
Then you can simply use replace similarly.
Suppose you want to search and replace the second word some.
Then just see this question
In addition to that you can also do something like this:
function doit(str, tobereplaced, occurence, withwhat){
var res = str.split(tobereplaced);
console.log(res);
var foo = []
for (var i = 0; i < occurence; i++) {
foo.push(res[i]);
}
var bar = []
for (var j = occurence; j < res.length; j++) {
bar.push(res[i]);
}
return foo.join("")+withwhat+bar.join("");
}
var str = "ssfds some people may work for some thing new some thing again some again";
doit(str, "some", 2, "bomb");

You can use the match method of the string to get an array of all the occurrences:
text.match(/some/g)
You need the 'g' flag in the regex otherwise the match will stop after the first hit

Here is how you replace the 2nd instance:
'some people may work for some thing new.'.replace(/(\bsome\b.*?)\bsome\b/, "$1foo");
//=> some people may work for foo thing new.

use the function exec(text) instend of test(text)
replace your code:
var patt = /some/.test(text);
to:
var patt = /some/.exec(text);

Related

what is best way to match words from list to words from sentence in javascript?

i have two sentences and i would like to find all the words they share regardless of capitalization or punctuation.
currently this is what I am doing:
searchWords = sentence1.split(" ");
var wordList = sentence2.split(" ");
const matchList = wordList.filter(value => -1 !== searchWords.indexOf(value));
it works ok but obviously capitalization and punctuation cause issues.
i know i need to incorporate something like .match() in there but i don't know how to work with it. I am sure this is something someone has done before just havent found the code yet, any refrences are also appreciated.
Thank you,
Best
This dude.
If you're looking for any words that match you can use RegExp with String.prototype.replace and verify a match using String.prototype.search with a created RegExp and an i flag to allow case insensitivity.
function compare(str1, str2, matches = []) {
str1.replace(/(\w+)/g, m => str2.search(new RegExp(m, "i")) >= 0 && matches.push(m));
return matches;
}
console.log( compare("Hello there this is a test", "Hello Test this is a world") );
If you're looking for specific words that match you can use functional composition to split each string into an Array, filter each by possible matches, and then filter one against the other.
function compare(str1, str2, matchables) {
let containFilter = (a) => (i) => a.includes(i),
matchFilter = s => s.toLowerCase().split(" ").filter(containFilter(matchables));
return matchFilter(str1).filter(containFilter( matchFilter(str2) ));
}
let matchables = ["hello", "test", "world"];
console.log( compare("Hello there this is a test", "Hi Test this is a world", matchables) );
I think you may be over-thinking this. Would just converting both sentences to an array and using a for loop to cycle through the words work? For example:
var searchWords = sentence1.split(" ");
var wordList = sentence2.toLowerCase().split(" ");
var commonWords = [];
for(var i = 0; i < searchWords.length; i++){
if(wordList.includes(searchWords[i].toLowerCase())){
commonWords.push(searchWords[i])
}
}
console.log(commonWords);
Or some variation of that.
As for the punctuation, you could probably add .replace(/[^A-Za-z0-9\s]/g,"") to the end of searchWords[i].toLowerCase() as mentioned in the following answer: https://stackoverflow.com/a/33408855/10601203

JS What's the fastest way to display one specific line of a list?

In my Javascript code, I get one very long line as a string.
This one line only has around 65'000 letters. Example:
config=123&url=http://localhost/example&path_of_code=blablaba&link=kjslfdjs...
What I have to do is replace all & with an break (\n) first and then pick only the line which starts with "path_of_code=". This line I have to write in a variable.
The part with replace & with an break (\n) I already get it, but the second task I didn't.
var obj = document.getElementById('div_content');
var contentJS= obj.value;
var splittedResult;
splittedResult = contentJS.replace(/&/g, '\n');
What is the fastest way to do it? Please note, the list is usually very long.
It sounds like you want to extract the text after &path_of_code= up until either the end of the string or the next &. That's easily done with a regular expression using a capture group, then using the value of that capture group:
var rex = /&path_of_code=([^&]+)/;
var match = rex.exec(theString);
if (match) {
var text = match[1];
}
Live Example:
var theString = "config=123&url=http://localhost/example&path_of_code=blablaba&link=kjslfdjs...";
var rex = /&path_of_code=([^&]+)/;
var match = rex.exec(theString);
if (match) {
var text = match[1];
console.log(text);
}
Use combination of String.indexOf() and String.substr()
var contentJS= "123&url=http://localhost/example&path_of_code=blablaba&link=kjslfdjs...";
var index = contentJS.indexOf("&path_of_code"),
substr = contentJS.substr(index+1),
res = substr.substr(0, substr.indexOf("&"));
console.log(res)
but the second task I didn't.
You can use filter() and startsWith()
splittedResult = splittedResult.filter(i => i.startsWith('path_of_code='));

Javascript regex replace with different values

I'd like to know if it is possible to replace every matching pattern in the string with not one but different values each time.
Let's say I found 5 matches in a text and I want to replace first match with a string, second match with another string, third match with another and so on... is it achievable?
var synonyms = ["extremely", "exceedingly", "exceptionally", "especially", "tremendously"];
"I'm very upset, very distress, very agitated, very annoyed and very pissed".replace(/very/g, function() {
//replace 5 matches of the keyword every with 5 synonyms in the array
});
You may try to replace the matches inside a replace callback function:
var synonyms = ["extremely", "exceedingly", "exceptionally", "especially", "tremendously"];
var cnt = 0;
console.log("I'm very upset, very distress, very agitated, very annoyed and very pissed (and very anxious)".replace(/very/g, function($0) {
if (cnt === synonyms.length) cnt = 0;
return synonyms[cnt++]; //replace 5 matches of the keyword every with 5 synonyms in the array
}));
If you have more matches than there are items in the array, the cnt will make sure the array items will be used from the first one again.
A simple recursive approach. Be sure your synonyms array has enough elements to cover all matches in your string.
let synonyms = ["extremely", "exceedingly", "exceptionally"]
let yourString = "I'm very happy, very joyful, and very handsome."
let rex = /very/
function r (s, i) {
let newStr = s.replace(rex, synonyms[i])
if (newStr === s)
return s
return r(newStr, i+1)
}
r(yourString, 0)
I would caution that if your replacement would also match your regex, you need to add an additional check.
function replaceExpressionWithSynonymsInText(text, regX, synonymList) {
var
list = [];
function getSynonym() {
if (list.length <= 0) {
list = Array.from(synonymList);
}
return list.shift();
}
return text.replace(regX, getSynonym);
}
var
synonymList = ["extremely", "exceedingly", "exceptionally", "especially", "tremendously"],
textSource = "I'm very upset, very distress, very agitated, very annoyed and very pissed",
finalText = replaceExpressionWithSynonymsInText(textSource, (/very/g), synonymList);
console.log("synonymList : ", synonymList);
console.log("textSource : ", textSource);
console.log("finalText : ", finalText);
The advantages of the above approach are, firstly one does not alter the list of synonyms,
secondly working internally with an ever new copy of the provided list and shifting it,
makes additional counters obsolete and also provides the opportunity of being able to
shuffle the new copy (once it has been emptied), thus achieving a more random replacement.
Using the example you've provided, here's what I would do.
First I would set up some variables
var text = "I'm very upset, very distress, very agitated, very annoyed and very pissed";
var regex = /very/;
var synonyms = ["extremely", "exceedingly", "exceptionally", "especially", "tremendously"];
Then count the number of matches
var count = text.match(/very/g).length;
Then I would run a loop to replace the matches with the values from the array
for(var x = 0; x < count; x++) {
text = text.replace(regex, synonyms[x]);
}
You can do it with the use of Replace() function, where you use 'g' option for global matching (finds all occurrences of searched expression). For the second argument you can use a function which returns values from your predefined array.
Here is a little fiddle where you can try it out.
var str = "test test test";
var rep = ["one", "two", "three"];
var ix = 0;
var res = str.replace(/test/g, function() {
if (ix == rep.length)
ix = 0;
return rep[ix++];
});
$("#result").text(res);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="result">
Result...
</p>
Yes it is achievable. There may be a more efficient answer than this, but the brute force way is to double the length of your regex. i.e. Instead of searching just A, search (/A){optionalText}(/A) and then replace /1 /2 as needed. If you need help with the regex itself, provide some code for what you're searching for and someone with more rep than me can probably comment the actual regexp.

Regex: .exec() function not returning expected output

This doesn't return what I, or regex101, expects:
var myString = "Accel World|http://www.anime-planet.com/anime/accel-worldAh! My Goddess|http://www.anime-planet.com/anime/ah-my-goddess";
var reg = /[^|]*/g;
var regResponse = reg.exec(myString);
console.log(regResponse);
according to regex101, this should match everything except '|' and return it yet it only matches the first string, Accel World, as opposed to everything but '|'.
How do I fix this?
Exec will only return one result at a time (subsequent calls will return the rest, but you also need to use the + instead of *)
You could use the myString.match(reg) htough to get all results in one go.
var myString = "Accel World|http://www.anime-planet.com/anime/accel-worldAh! My Goddess|http://www.anime-planet.com/anime/ah-my-goddess";
var reg = /[^|]+/g;
var regResponse = myString.match(reg);
console.log(regResponse);
You need to loop .exec() to retrieve all matches. The documentation says
If your regular expression uses the "g" flag, you can use the exec()
method multiple times to find successive matches in the same string.
var reg = /[^|]+/g;
while(regResponse = reg.exec(myString)) {
console.log(regResponse);
}
Try a "+" instead of the "*"
So,
var reg = /[^|]+/g;

RegExp to match words wrapped in braces

In javascript, I've got a block of HTML like this:
<h2>{title}</h2>
<p>{content}</p>
And I'm trying use regex "match" to spit out an array of all the {item}'s. So my output should look like:
['title', 'url', 'content']
I've gotten as far as:
var pattern = new RegExp("\{[a-zA-Z]+\}+");
var match = pattern.exec("{Sample} bob {text}");
But it's only returning the first tag.
This is just beyond my regex skills. Can anyone help?
Cheers!
You need to create a pattern with the global flag:
var pattern = new RegExp("\{[a-zA-Z]+\}", "g");
or:
var pattern = /\{[a-zA-Z]+\}/g;
Then you can call the match() method on your string to get a list of matches:
var matches = "{Sample} bob {text}".match(pattern);
I think you want:
var pattern = new RegExp("\{[a-zA-Z]+\}+", "g");
The second option is a flag telling it to search the entire string and return all matches.
See: http://www.evolt.org/article/Regular_Expressions_in_JavaScript/17/36435/ for more details.
Have you tried this yet?
<script>
var text = '<h2>{title}</h2>\n<p>{content}</p>';
var regex = /\{[a-z]+\}/ig;
var result = text.match(regex);
for (var i = 0; i < result.length; i++) {
console.debug(i + ". " + result[i]);
}
/*
gives:
0. {title}
1. {test}
2. {url}
3. {content}
*/
</script>
Much as I like to roll my own RegExp (and you really just need the global flag), have you looked at prototype templates, Trimpath JST or anything like that?
Because possibly rolling your own won't be as efficient for reuse as the above examples. EG:
String.prototype.template = function (obj) {
return this.replace(/{([^{}]+)}/g,
function (full, word) {
return((typeof obj[word]==='string'||typeof obj[word]==='number')?obj[word]:full);
}
);
};
"The {adj1} {adj2} {noun}.".template({adj1: 'lazy',adj2: 'brown', noun: 'dog'})
==> "The lazy brown dog."
This runs your regex each time, while I believe the prototype templates basically does it once.
I got off path by using exec for testing.

Categories

Resources