Compare two strings and return different stretch - javascript

I have two strings like these:
var str1 = "lorem ipsum dolor sit amet";
var str2 = "ipsum dolor";
And I'm trying to compare them and get, as result, an array with everything that doesn't match this comparation and the match! One for the beggining and the other one for the ending.
E.g: In this case above, the return should be an array like this:
result[0] //should keep the begining **"lorem "** (with the blank space after word)
result[1] // should keep the ending **" sit amet"** (with the blank space before word)
result[2] // should keep the match **"ipsum dolor"**
All I got was an elegant solution posted by #Mateja Petrovic. But I can get this values separately.
Just like this:
const A = "ipsum dolor"
const B = "lorem ipsum dolor sit amet"
const diff = (diffMe, diffBy) => diffMe.split(diffBy).join('')
const C = diff(B, A)
console.log(C) // jumps over the lazy dog.
I'm really stuck! Any idea?
Thanks a lot!

const diff = (str, query) => [...str.split(query), query];
/*
1. we split the string into an array whenever query is found
2. we spread (...) the array into a new array
3. we add the query at the end of the new array
*/
var str = "lorem ipsum dolor sit amet";
var query = "ipsum dolor";
const result = diff(str, query)
console.log(result)
console.log(result[0])
console.log(result[1])
console.log(result[2])

I don't think what you are asking is logically possible. a "string" can be a single letter, which is going to get very messy. at best maybe something like this?
var str1 = "lorem ipsum dolor sit amet";
var str2 = "ipsum dolor";
var parts = str1.split(str2);
console.log(parts); // ['lorem ', ' sit amet']

You could split the target string by the search string, and append the latter to the solution.
const haystack = 'lorem ipsum dolor sit amet';
const needle = 'ipsum dolor';
const diff = (needle, haystack) =>
[...haystack.split(needle), needle]
console.log(diff(needle,haystack));
// ["lorem ", " sit amet", "ipsum dolor"]

Related

Replace a character of a string

I have a string that looks like this: [TITLE|prefix=a].
From that string, the text |prefix=a is dynamic. So it could be anything or empty. I would like to replace (in that case) [TITLE|prefix=a] with [TITLE|prefix=a|suffix=z].
So the idea is to replace ] from a string that starts with [TITLE with |suffix=z].
For instance, if the string is [TITLE|prefix=a], it should be replaced with [TITLE|prefix=a|suffix=z]. If it's [TITLE], it should be replaced with [TITLE|suffix=z] and so on.
How can I do this with RegEx?
I have tried it this way but it gives an error:
let str = 'Lorem ipsum [TITLE|prefix=a] dolor [sit] amet [consectetur]';
const x = 'TITLE';
const regex = new RegExp(`([${x})*]`, 'gi');
str = str.replace(regex, "$1|suffix=z]");
console.log(str);
I have also tried to escape the characters [ and ] with new RegExp(`(\[${x})*\]`, 'gi'); but that didn't help.
You need to remember to use \\ in a regular string literal to define a single literal backslash.
Then, you need a pattern like
/(\[TITLE(?:\|[^\][]*)?)]/gi
See the regex demo. Details:
(\[TITLE\|[^\][]*) - Capturing group 1:
\[TITLE - [TITLE text
(?:\|[^\][]*)? - an optional occurrence of a | char followed with 0 or more chars other than ] and [
] - a ] char.
Inside your JavaScript code, use the following to define the dynamic pattern:
const regex = new RegExp(`(\\[${x}\\|[^\\][]*)]`, 'gi');
See JS demo:
let str = 'Lorem ipsum [TITLE|prefix=a] dolor [sit] amet [consectetur] [TITLE]';
const x = 'TITLE';
const regex = new RegExp(`(\\[${x}(?:\\|[^\\][]*)?)]`, 'gi');
str = str.replace(regex, "$1|suffix=z]");
console.log(str);
// => Lorem ipsum [TITLE|prefix=a|suffix=z] dolor [sit] amet [consectetur]
I think the solution to your problem would look similar to this:
let str = 'Lorem ipsum [TITLE|prefix=a] dolor [sit] amet [consectetur]';
str = str.replace(/(\[[^\|\]]+)(\|[^\]]*)?\]/g, "$1$2|suffix=z]");
console.log(str);

Regex get the middle section of each word javascript

So essentially what I'm trying to do is loop through every word in a html document and replace the first letter of each word with 'A', the second - second last letter with 'b' and the last letter with 'c', completely replacing the word. I'm not sure if regular expressions are the way to go about doing this (should I instead be using for loops and checking each character?) however I'll ask anyway.
Currently I'm doing:
document.body.innerHTML = document.body.innerHTML.replace(/\b(\w)/g, 'A'); to get the first letter of each word
document.body.innerHTML = document.body.innerHTML.replace(/\w\b/g, 'c'); to get the last letter of each word
So if I had the string: Lorem ipsum dolor sit amet I can currently make it Aorec Apsuc Aoloc Aic Amec but I'd like to do Abbbc Abbbc Abbbc Abc Abbc in javascript.
Any help is much appreciated - regular expressions really confuse me.
You almost got it.
str = "Lorem ipsum dolor sit amet"
str = str
.replace(/\w/g, 'b')
.replace(/\b\w/g, 'A')
.replace(/\w\b/g, 'c')
document.write(str);
Fancier replacement rules can be handled with a callback function, e.g.
str = "Lorem ipsum dolor sit amet"
str = str.replace(/\w+/g, function(word) {
if (word === "dolor")
return word;
return 'A' + 'b'.repeat(word.length - 2) + 'c';
});
document.write(str);

How to make character count with Javascript

How to correctly make a character count with JS.
My code seems is incorrect, what i'm doign wrong?
<p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
var str = document.getElementsByClassName('text');
var res = str.innerHTML = str.value.length;
console.log(res);
This can work for you
var x = document.getElementById("text").innerHTML
var str = x.length;
alert("length is:" +str);
console.log(str);
<p id="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
If you look at this definition of the function it returns an array. So you either want the length of the array str.length or to iterate through the array.
getElementsByClassName() returns an array-like collection of elements. Iterate over it and fetch the value:
var str = document.getElementsByClassName('text');
[].forEach.call(str, function(el){
var res = el.value.length;
el.innerHTML = res;
console.log(res);
});
I guess you want to get the length of the content of an element. For that you should be using id selector, not class selector, there can be many elements with the same class but not with the same id. So you should give it some id like: <p id='some_id' class='text'>
Now you can get it through:
document.getElementById("some_id").innerHTML.length
To avoid any leading or trailing spaces, and to get exact length of text, you can try this:
document.getElementById("some_id").innerHTML.trim().length

Regex string with pattern

For Regex fans... What I have is this string:
"Lorem ipsum dolor FOO IO BAR BA"
I'd like to extract the Title, and an Array of the UPPERCASE suffixes:
"Lorem ipsum dolor"
["FOO", "IO", "BAR", "BA"]
Here's my attempt:
function retrieveGroups( string )
{
var regexp = new RegExp(/(FOO|BAR|BA|IO)/g);
var groups = string.match( regexp ) || [];
var title = string.replace( regexp, "" );
return {title:title, groups:groups};
}
results in:
title : "Lorem ipsum dolor ",
groups : ["FOO" , "IO", "BAR", "BA"]
which is great, but It'll not prevent this cases:
LoremFOO ipBAsum IO dolor FOO
where in that cas I need only ["FOO"] in the resulting group.
The rule seems simple...
Get the title.
Title could be all uppercase ("LOREM IPSUM").
Get an array of uppercase suffixes.
Grouops (FOO,BAR,IO,BA) might not be present in the string.
Don't match suffix if it's not: a suffix and is not lead by a whitespace
Start matching from end of string (if possible?) so don't match duplicate Group parameters if encountered (issue example above)
I've also tried to string.replace(regexp, function(val) .... but I'm not sure how it could help...
Don't know if it helps but fiddle is here. Thank you!
To get an array of uppercase suffixes.
> "Lorem ipsum dolor FOO IO BAR BA".match(/\b[A-Z]+\b(?!\s+\S*[^A-Z\s]\S*)/g)
[ 'FOO',
'IO',
'BAR',
'BA' ]
> "LoremFOO ipBAsum IO dolor FOO".match(/\b[A-Z]+\b(?!\s+\S*[^A-Z\s]\S*)/g)
[ 'FOO' ]
To get the title array.
> "LoremFOO ipBAsum IO dolor FOO".match(/^.*?(?=\s*\b[A-Z]+\b(?:\s+[A-Z]+\b|$))/g)
[ 'LoremFOO ipBAsum IO dolor' ]
> "Lorem ipsum dolor FOO IO BAR BA".match(/^.*?(?=\s*\b[A-Z]+\b(?:\s+[A-Z]+\b|$))/g)
[ 'Lorem ipsum dolor' ]
Update:
> "LoremFOO ipBAsum IO dolor FOO".match(/\b(?:FOO|BAR|BA|IO)\b(?!\s+\S*[^A-Z\s]\S*)/g)
[ 'FOO' ]
\b called word boundary which matches between a word character and a non-word character.
(?:FOO|BAR|BA|IO)\b matches FOO or BAR or BA or IO and also the following word boundary,
(?!\s+\S*[^A-Z\s]\S*) only if it's not followed by one or more space character , zero or more non-space characters and a character other than a space or an uppercase letter, again followed by zero or more non-space characters. So this fails for IO because it's followed by a word which contain atleast one lowercase letter. (?!...) called negative lookahead assertion.
> "Lorem ipsum dolor FOO IO BAR BA".match(/\b(?:FOO|BAR|BA|IO)\b(?!\s+\S*[^A-Z\s]\S*)/g)
[ 'FOO',
'IO',
'BAR',
'BA' ]
And also, you could use a positive lookahead based regex also. (?=....) called positive lookahead assertion.
> "LoremFOO ipBAsum IO dolor FOO".match(/\b(?:FOO|BAR|BA|IO)\b(?=\s+(?:FOO|BAR|BA|IO)\b|$)/g)
[ 'FOO' ]
To get the title array.
> "Lorem ipsum dolor FOO IO BAR BA".match(/^.*?(?=\s*\b(?:FOO|BAR|BA|IO)\b(?:\s+(?:FOO|BAR|BA|IO)\b|$))/g)
[ 'Lorem ipsum dolor' ]
> "LoremFOO ipBAsum IO dolor FOO".match(/^.*?(?=\s*\b(?:FOO|BAR|BA|IO)\b(?:\s+(?:FOO|BAR|BA|IO)\b|$))/g)
[ 'LoremFOO ipBAsum IO dolor' ]
Maybe this is what you are looking for:
function retrieveGroups( string )
{
var regexp = new RegExp(/^(.*?)\s*([ A-Z]+)*$/);
var result = string.match( regexp ) || [];
var title = result[1];
var groups=result[2].split(" ");
return {title:title, groups:groups};
}
Edit:
Here a solution for a fixed set of Uppercase Words:
function retrieveGroups( string )
{
var regexp = new RegExp(/^(.*?)\s*((?:\s|FOO|BAR|IO|BA)+)?$/);
var result = string.match( regexp ) || [];
var title = result[1];
var groups=result[2].split(" ");
return {title:title, groups:groups};
}
By using Avinash's RegEx one can extract all the valid suffixes.
The title would be all text before the first suffix.
So the final JavaScript code will look like below:
var arr = ['Lorem ipsum dolor FOO IO BAR BA', 'LoremFOO ipBAsum IO dolor FOO']
arr.forEach(function(str) {
var o = retrieveGroups(str);
alert("Parsed title = " + o.title + ", groups=" + o.groups);
});
function retrieveGroups( string ) {
var regex = /\b(?:FOO|BAR|BA|IO)\b(?=\s+(?:FOO|BAR|BA|IO)\b|$)/g
var groups = string.match( regex ) || [];
var title = string.replace( regex, '').trim();
return {'title':title, 'groups':groups};
}
Here is DEMO

Split content in last parantheses

In javascript, how can I split string to get content of last parantheses so
var str = "Lorem ipsum (I don't want this data) lorem ipsum (I want this data)";
becames array
["Lorem ipsum (I don't want this data) lorem ipsum "],["I want this data"]
You can use a regular expression and match :
var arr = str.match(/^(.*)\(([^\)]+)\)$/).slice(1);
This produces exactly
["Lorem ipsum (I don't want this data) lorem ipsum ", "I want this data"]
Online explanation of the regex
I always prefer approaches without regex, mainly for performance. It may not be pretty, but it works nontheless!
var str = "Lorem ipsum (I don't want this data) lorem ipsum (I want this data)";
var s = str.lastIndexOf('(');
var e = str.lastIndexOf(')');
var l = e - s;
var data = [
str.substr(0, s).trim(),
str.substr(s + 1, l - 1).trim()
];
// data = ["Lorem ipsum (I don't want this data) lorem ipsum", "I want this data"]

Categories

Resources