How to extract question mark surrounded texts into an array in Javascript - javascript

I have a string like this,
var str = " This is a ?sample? text to ?extract? question marks separated texts into an array in ?Javascript?. "
I want a javascript array as below,
arr = {
'sample',
'extract',
'Javascript'
}

You can alternate between keeping and ignoring letters each time you get to a "?". This will not include the text after an opening ? if there is no closing ?.
let str = "This ?? should ?only? leave ?four words? ?in? the ?result?. Ignoring if there is no ? closing question mark"
let result = []
let openingQuestionMark = false
let substring = ""
for (let key of str) {
if (key === "?") {
if (openingQuestionMark) {
substring && result.push(substring)
substring = ""
}
openingQuestionMark = !openingQuestionMark
continue
}
if (openingQuestionMark) {
substring += key
}
}
console.log(result)

You can split() and then filter() the results having an odd index :
// After the split('?'), an array will be created. One needs the odd indexes
// 0 1 2 3 4 5 6 7
const str = " This is a ?sample? text to ?extract? question marks separated texts into an array in ?Javascript?. ?";
const arr = str.split('?').filter((word, index) => index % 2 !== 0 && word !== '');
console.log(arr);
This will be working only if you are sure that the input contains only an even number of ?. An input like "foo?bar" will output [ 'bar' ].
To make sure this work with any input, you can use RegEx :
function getWordsBetweenParenthesis(input)
{
const pattern = /(?:\?)(.*?)(?:\?)/gm;
const matches = input.matchAll(pattern);
return [...matches].map(arr => arr[1]);
}
console.log(getWordsBetweenParenthesis(" This is a ?sample? text to ?extract? question marks separated texts into an array in ?Javascript?. "));
console.log(getWordsBetweenParenthesis("foo?bar"));
console.log(getWordsBetweenParenthesis("foo??bar"));
console.log(getWordsBetweenParenthesis("?hello?World?"));
console.log(getWordsBetweenParenthesis("?hello??World?"));

Related

How to check if string has vowels? [duplicate]

This question already has answers here:
Counting the vowels in a string using Regular Expression
(2 answers)
Closed 1 year ago.
I tried to write a function which checks if a given string contains vowels and I cannot see why it works for some words 'cat' and 'why' but not 'DOG', i believe that i have accounted for uppercase.
const containsVowels = string => {
var lowerCase = string.toLowerCase();
var word = lowerCase.split("");
var vowelsArray = ["a","o","i","u","y"];
const result = word.filter(letter => vowelsArray.includes(letter));
return result.includes("a","o","i","u","y");
};
includes takes only 2 parameters, the first one being searchElement and second parameter being fromIndex.
Reference : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes#parameters
You wouldn't want to do the last check if the result array contains vowels or not, because in the previous step itself you are filtering out the word to get array that contains only vowels. So just check if the array is empty or it contains any elements inside it.
const containsVowels = str => {
let lowerCase = str.toLowerCase();
let word = lowerCase.split("");
let vowelsArray = ["a","o","i","u","y"];
const result = word.filter(letter => vowelsArray.includes(letter));
return result.length > 0;
};
console.log(containsVowels("cat"));
console.log(containsVowels("DOG"));
console.log(containsVowels("BCDF"));
Suggestion: Don't use built in keywords as variables.
As pointed out by Muhammad, we can regex to find if the string contains vowels
const containsVowel = str => {
const vowelRegex = /[aeiou]/i;
return vowelRegex.test(str);
};
2 Problems,
Why would you use includes twice ?
&
You cannot use includes like
result.includes("a","o","i","u","y");
includes only accepts 2 param:
includes(searchElement, fromIndex)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
By filtering, you already know the result.
What you should do is, compare the length of the result:
const containsVowels = string => {
let lowerCase = string.toLowerCase();
let word = lowerCase.split("");
let vowelsArray = ["a","o","i","u","y"];
const result = word.filter(letter => vowelsArray.includes(letter));
return result.length > 0 ? true : false
};
use regex to get the result.
var regEx = /[aeiou]/gi
var test_string = "Cat";
var match = test_string.match(regEx)
if(match)
console.log("Match found", match)
when you write something like this
result.includes("a","o","i","u","y")
this compare with only it's first element which is "a" and one thing you don't need to write the above mentioned code further.
After filtering just replace the above code with
return result.length > 0 ? true : false

How can I put the <br> tag in a long string after every 5 words? [duplicate]

This question already has answers here:
How can I break up a javascript string with a new line every five words?
(4 answers)
Closed 3 years ago.
Example:
let str = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
I want to put the <br> tag after every 5 words like so:
let str1 = "Hello this is a test<br>string to figure out how<br>is it possible to split<br>a long string into multiple<br>string";
How can I do this?
You can split the string on spaces, map the elements of resulting Array to either words preceded by space or every 6th word by <br> and join the result back to a String. Something like:
const str2Split = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
const withAddedBreaks = str2Split.split(" ")
.map( (v, i) => `${i && i % 5 == 0 ? "<br>" : " "}${v}`);
// ^ insert <br> after every 5 words, otherwise a space
console.log(withAddedBreaks.join("").trim());
// ^ remove first space
console.log(`use method: replace every 4rd space with " !#! "\n${
replaceEveryNthSpace(str2Split, 3, " !#! ")}`);
// a method for it
function replaceEveryNthSpace(str, n, substr) {
return str
.split(" ")
.map( (v, i) => `${i && i % n == 0 ? substr : " "}${v}`)
.join("")
.trim();
}
You've got a bunch of working answers with different approaches but none that uses RegExp so here I'll contribute with one that does:
str1 = str.match(/([^ ]+ +){5}|.+/g).join('<br>');
([^ ]+ +) matches non-spaces (i.e. words) followed by spaces. {5} means it has to match this five times in a row, giving us the match of five words with spaces in between. |.+ is to include anything that remains of the string after the last five word match. The g flag is needed because without it, it would only match a single occurrence. The matches end up in an array, which we join() with '<br>'.
This should do it:
str
.split(' ')
.reduce((accumulator, word, index) =>
accumulator + word + (index !== 0 && index % 5 === 0 ? '<br>' : ' ')
, '');
So what happens here is we split the string into an array of words using the space character. Then we iterate over the array using Array.prototype.reduce and add each word back on to an accumulator string along with a space, or a <br> tag if it the array index is a multiple of 5.
Try like this
let defaultStr = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
let field = document.getElementById('string');
window.onload = function() {
field.innerHTML = defaultStr;
};
function addBr(){
const arrayWords = defaultStr.split(' ');
let str = '';
let numAddBr = 5;
arrayWords.forEach((value, numberWord) => {
numberWord++;
if(numberWord % numAddBr === 0) str+= '<br>'
str+= `${value} `;
})
field.innerHTML = str
}
<div id="string"></div>
<button onclick="addBr()">add Br</button>
You may use filter with initial result like the first element is final result and the last is the index of the current word, every 5 word, we put the <br> to the final array word and recalculate the current index, the last step is join the word array and replace the unnecessary empty string like this:
let str = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
let result = str.split(" ").reduce((rs, el) =>
{
if (rs[1] == 5) {
rs[0].push("<br>")
rs[1] = 0
}
else {
rs[0].push(el)
rs[1]++;
}
return rs;
}
,[[], 0]
)[0].join(" ").replace(/ <br>/g, "<br>");
console.log(result);
var str = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
var new_str="";
str.split(" ").forEach(function (val,i){new_str += val+((i+1)%5==0?"<br>":" ");});
console.log(new_str);
document.write(new_str);
What if multiple spaces are present between two words?
Use this function:
function addtext(str,gap_len,texttoaddbetweenstr){
var new_str="";
str=str.replace(/ {1,}/g," ");
str.split(" ").forEach(function (val,i){new_str += val+((i+1)%gap_len== 0 ? texttoaddbetweenstr:" ");});
return new_str;
}
var str1 = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
var str_with_multiple_spaces = "Hello this is a test string to figure out how is it possible to split a long string into multiple string";
console.log(addtext(str1,5,"<br>"));
console.log(addtext(str_with_multiple_spaces,5,"<br>"));
console.log(addtext(str1,1,"|"));
console.log("To remove spaces: "+addtext(str1,1,""));

How to replace words in string and ignore numbers in string

What i'm trying to achieve is searching value in array if it matches specific variable, then replace it with other variable (which is translation for this word), array value consist number and i need only to translate words without touching the number. Here is an example.
var arr = ["18 pages"];
var item = "18 pages";
var translate = "pagina's";
if(arr.indexOf(item) !== -1) {
arr[0] = arr[0].replace(/[^0-9 ]/, translate);
alert(arr);
}
Output is: 18 pagina'sages
Expected output: 18 pagina's
So it needs only to translate words and keep numbers.
How can i do it properly?
Another possibility for solving this problem would be to find multiple characters surrounded by boundaries and replace these. This would be the regular expression: \b[a-zA-Z]+\b. Here is an executable example:
let arr = ["18 pages"];
let item = "18 pages";
let translate = "pagina's";
if (arr.indexOf(item) !== -1) {
arr[0] = arr[0].replace(/\b[a-zA-Z]+\b/, translate);
console.log(arr);
}
If you run this snippet you will get the expected output: 18 pagina's.
Update:
Another alternative which would first match a character and then match any characters excluding numbers ([a-zA-Z][^0-9]+) would be able to replace more complex expressions and not just a single word.
Here is a running example based on the fiddle in https://jsfiddle.net/9uta5bo4/2/:
let arr = "18 pagina’s per minuut";
let item = "pagina’s per minuut";
let translate = "pages par minute";
if (arr.indexOf(item) !== -1) {
arr = arr.replace(/[a-zA-Z][^0-9]+/, translate);
console.log(arr);
}
If you run this fiddle you will see the output:
18 pages par minute
Another alternative to [a-zA-Z][^0-9]+ is [^0-9 ][^0-9]+ which finds any character which is not a number or space first and then anything which is not a number multiple times.
You're only matching a single character with [^0-9 ]. I suspect you want [^0-9 ]+.
let arr = ["18 pages"];
let item = "18 pages";
let translate = "pagina's";
if (arr.indexOf(item) !== -1) {
var res = arr[0].replace(/[a-zA-Z]+/g, translate); //replace only letters
var res2 = arr[0].replace(/[^0-9|\s]+/g, translate); // ecxlcude numbers and space
var res3 = arr[0].replace(/[^\d|\s]+/, translate); // ecxlcude numbers and space
console.log(res);
console.log(res2);
console.log(res3);
}

Need to split University Course code into prefix and suffix using regex

I need to split a a university course code into prefix and suffix. e.g. CSE1011 into Prefix CSE and Suffix 1011 . Prefix may be 2 or more Alphabets and suffix may be none/ 3 or more. So far I have come up with this RegEx:
/([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
var splitted = courseRegex.exec(courscrCode);
console.log(splitted);
Also tried This. I am getting more match
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
if (courscrCode.match(courseRegex)) {
var splitted = courscrCode.split(courseRegex);
console.log(splitted.length);
if (splitted.length > 1) {
splitted.forEach(function(value, index) {
if ((value != '') && (value != undefined))
console.log(value, index);
});
}
} else {
console.log('course code mangled');
}
I need a solution where i am going to get exactly 2 sub-string prefix and suffix. now I am getting more that 2. I am also open to any other solution
As Terry noted above, MDN states that the array returned by regex will always include the matched text as the first item. The code below will remove the first element.
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
var splitted = courseRegex.exec(courscrCode);
splitted.splice(0,1);
console.log(splitted);
Your splitted array in SECOND sample code is:
["", "CSE", "1011", ""]
If your input text courscrCode is always one course code, you should find prefix in [1] and number in [2]
If input text may be more than just course code to validate, some changes are required.
Note: first empty item in array is all characters before CSE and last item in array is all characters after 1011. It's not whole matched value
var courscrCode = 'CSE1011';
var courseRegex = /([A-Z]{2,})(?:\s*)([0-9]{3,})?$/g;
var prefix = '' ;
var suffix = '' ;
if (courscrCode.match(courseRegex)) {
var splitted = courscrCode.split(courseRegex);
console.log(splitted.length);
if (splitted.length > 1) {
prefix = splitted[1];
suffix = splitted[2];
//or:
splitted.splice(0,1);
splitted.splice(2,1);
console.log(splitted);
}
} else {
console.log('course code mangled');
}

How to capitalize the last letter of each word in a string

I am still rather new to JavaScript and I am having an issue of getting the first character of the string inside the array to become uppercase.
I have gotten to a point where I have gotten all the texted lowercase, reversed the text character by character, and made it into a string. I need to get the first letter in the string to uppercase now.
function yay () {
var input = "Party like its 2015";
return input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
input[i] = input[i].charAt(0).toUpperCase() + input[i].substr(1);
}
}
console.log(yay());
I need the output to be "partY likE itS 2015"
Frustrating that you posted your initial question without disclosing the desired result. Lots of turmoil because of that. Now, that the desired result is finally clear - here's an answer.
You can lowercase the whole thing, then split into words, rebuild each word in the array by uppercasing the last character in the word, then rejoin the array:
function endCaseWords(input) {
return input.toLowerCase().split(" ").map(function(item) {
return item.slice(0, -1) + item.slice(-1).toUpperCase();
}).join(" ");
}
document.write(endCaseWords("Party like its 2015"));
Here's a step by step explanation:
Lowercase the whole string
Use .split(" ") to split into an array of words
Use .map() to iterate the array
For each word, create a new word that is the first part of the word added to an uppercased version of the last character in the word
.join(" ") back together into a single string
Return the result
You could also use a regex replace with a custom callback:
function endCaseWords(input) {
return input.toLowerCase().replace(/.\b/g, function(match) {
return match.toUpperCase();
});
}
document.write(endCaseWords("Party like its 2015"));
FYI, there are lots of things wrong with your original code. The biggest mistake is that as soon as you return in a function, no other code in that function is executed so your for loop was never executed.
Then, there's really no reason to need to reverse() the characters because once you split into words, you can just access the last character in each word.
Instead of returning the result splitting and reversing the string, you need to assign it to input. Otherwise, you return from the function before doing the loop that capitalizes the words.
Then after the for loop you should return the joined string.
Also, since you've reverse the string before you capitalize, you should be capitalizing the last letter of each word. Then you need to reverse the array before re-joining it, to get the words back in the original order.
function yay () {
var input = "Party like its 2015";
input = input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = input[i].substring(0, len) + input[i].substr(len).toUpperCase();
}
return input.reverse().join(" ");
}
alert(yay());
You can use regular expression for that:
input.toLowerCase().replace(/[a-z]\b/g, function (c) { return c.toUpperCase() });
Or, if you can use arrow functions, simply:
input.toLowerCase().replace(/[a-z]\b/g, c => c.toUpperCase())
Here's what I would do:
Split the sentence on the space character
Transform the resulting array using .map to capitalize the first character and lowercase the remaining ones
Join the array on a space again to get a string
function yay () {
var input = "Party like its 2015";
return input.split(" ").map(function(item) {
return item.charAt(0).toUpperCase() + item.slice(1).toLowerCase();
}).join(" ");
}
console.log(yay());
Some ugly, but working code:
var text = "Party like its 2015";
//partY likE itS 2015
function yay(input) {
input = input.split(' ');
arr = [];
for (i = 0; i < input.length; i++) {
new_inp = input[i].charAt(0).toLowerCase() + input[i].substring(1, input[i].length - 1) + input[i].charAt(input[i].length - 1).toUpperCase();
arr.push(new_inp);
}
str = arr.join(' ');
return str;
}
console.log(yay(text));
Try using ucwords from PHP.js. It's quite simple, actually.
String.prototype.ucwords = function() {
return (this + '')
.replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function($1) {
return $1.toUpperCase();
});
}
var input = "Party like its 2015";
input = input.charAt(0).toLowerCase() + input.substr(1);
input = input.split('').reverse().join('').ucwords();
input = input.split('').reverse().join('');
Note: I modified their function to be a String function so method chaining would work.
function yay(str)
{
let arr = str.split(' ');
let farr = arr.map((item) =>{
let x = item.split('');
let len = x.length-1
x[len] = x[len].toUpperCase();
x= x.join('')
return x;
})
return farr.join(' ')
}
var str = "Party like its 2015";
let output = yay(str);
console.log(output) /// "PartY likE itS 2015"
You can split and then map over the array perform uppercase logic and retun by joining string.
let string = "Party like its 2015";
const yay = (string) => {
let lastCharUpperCase = string.split(" ").map((elem) => {
elem = elem.toLowerCase();
return elem.replace(elem[elem.length - 1], elem[elem.length - 1].toUpperCase())
})
return lastCharUpperCase.join(" ");
}
console.log(yay(string))

Categories