Convert End Quote to Apostrophe Javascript - javascript

The below two strings have different apostrophes. I am pretty stumped on how to convert them so that they are the same style (both are either slanted or both are either straight up and down). I have tried everything from enclosing it in `${}`` to regex expressions to remove and replace. I am not sure how it is being stored like this but when I try to search for string1 inside of string2 it doesn't recognize the index because (I believe) of the mismatch apostrophe. Has anyone run into this before?
//let textData = Father’s
//let itemData = Father's Day
const newData = currData.filter(item => {
let itemData = `${item.activityName.toUpperCase()}`;
let textData = `${text.toUpperCase()}`; //coming in slanted
let newItemData = itemData.replace(/"/g, "'");
let newTextData = textData.replace(/"/g, "'");
return newItemData.indexOf(newTextData) > -1;
});

first of all, your code won't run because you are not wrapping your string variables with ", ' or `, depending on the case.
if your string has ' you can use " or ` like this:
"Hello, I'm a dev"
or
"Hello, I`m a dev"
but you can not mix them if you have the same symbol, so this is not allowed:
'Hello, I`m a dev'
here you have a working example of your strings wrapped correctly and also replacing the values to match the strings.
note: please look that the index in this case is 0 because the whole string that we are looking matches from the 0 index to the length of the response1.
also I added a case if you want to get the partial string from string2 based on the match of string1
let string1 = "FATHER’S"
let string2 = "FATHER'S DAY: FOR THE FIXER"
const regex = /’|'/;
const replacer = "'";
let response1 = string1.replace(regex, replacer);
let response2 = string2.replace(regex, replacer);
console.log(response1);
console.log(response2);
console.log("this is your index --> ", response2.indexOf(response1));
console.log("string 2 without string 1 -->", response2.slice(response2.indexOf(response1) + response1.length, response2.length))

You could do a search using a regex, allowing for whatever apostrophe variations you expect:
let string1 = "FATHER’S"
let string2 = "FATHER'S DAY: FOR THE FIXER"
const regex = string1.split(/['’"`]/).join("['’\"`]")
//console.log(regex);
const r = new RegExp(regex)
console.log(string2.search(r)); //comes back as 0

Related

Get function names from specific string

I have string with slash separated contains function names.
e.g.
my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName()
Within above string I want only function name i.e. getCustomer(), getControllerName() & getCsvFileName()
I searched some regex like:
let res = myString.match(/(?<=(function\s))(\w+)/g);
but its returning result as null.
Update:
Now I want to get function names without parentheses () i.e. getCustomer, getControllerName & getCsvFileName
Please help me in this
const str = "my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName()"
let tokens = [];
for (element of str.split("/"))
if (element.endsWith("()"))
tokens.push(element.split("=")[1] ?? element.split("=")[0])
console.log(tokens);
General idea: split the string along slashes, and for each of these tokens, if the token ends with () (as per Nick's suggestion), split the token along =. Append the second index of the token split along = if it exists, otherwise append the first.
A "smaller" version (using purely array methods) could be:
const str = "my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName()"
let tokens = str.split("/")
.filter(element => element.endsWith("()"))
.map(element => element.split("=")[1] ?? element.split("=")[0]);
console.log(tokens);
You can split the string that has parentheses () first like /.*?\([^)]*\)/g.
This will give array of results, and after that you can iterate the array data and for each item, you can split the = and / before function name with the help of item.split(/=|\//).
Then push the filtered function name into empty array functionNames.
Working Example:
const string = `my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName()`;
const functionNames = [];
string.match(/.*?\([^)]*\)/g).forEach(item => {
const splitString = item.split(/=|\//);
const functionName = splitString[splitString.length - 1];
functionNames.push(functionName);
});
console.log(functionNames);
As per, MDN docs the match() method returns null if it does not find a match for the provided regex in the provided search string.
The regular expression which you have provided,/(?<=(function\s))(\w+)/g matches any word that has 'function ' before it. (NOTE: a space after the word function)
Your search string my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName() does not include 'function ' before any characters. That is why you got null as result of match() method.
let yourString = 'my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName()';
let myReferenceString = 'SAMPLETEXTfunction sayHi()/function sayHello()';
let res = yourString.match(/(?<=(function\s))(\w+)/g);
let res2 = myReferenceString.match(/(?<=(function\s))(\w+)/g);
console.log("Result of your string", res);
console.log("Result of my string", res2);
My solution here,
let myreferenceString = 'my_doc/desktop/customer=getCustomer()/getCsvFileName()/controller=getControllerName()'
let res = myreferenceString.match(/((?<==)(\w+\(\)))|((?<=\/)(\w+\(\)))/g);
console.log("Result", res);
NOTE: I have used the 'Positive Look Behind regex operator', This is not supported in browsers like Safari and IE. Please do reasearch about this before considering this approach.

Matching function name and arguments using regex

I have some strings in the following pattern
'walkPath(left, down, left)'
To extract the function name alone, and the arguments in an another array, i used those regular expressions:
const str = 'walkPath(left, down, left)'
const functionNameRegex = /[a-zA-Z]*(?=\()/
console.log(str.match(functionNameRegex)) //outputs ['walkPath'] ✅✅
const argsRegex = /(?![a-zA-Z])([^,)]+)/g
console.log(str.match(argsRegex)) //outputs [ '(left', ' down', ' left' ]
the first one worked fine. In the second regex, the '(' from from '(left' should be excluded, so it should be 'left'
Try this one:
/(?<=\((?:\s*\w+\s*,)*\s*)\w+/g
const str = 'walkPath(left, down, left)'
const functionNameRegex = /[a-zA-Z]*(?=\()/
console.log(str.match(functionNameRegex))
const argsRegex = /(?<=\((?:\s*\w+\s*,)*\s*)\w+/g
console.log(str.match(argsRegex))
It is not very restricted, if you really want to be safe, you can try:
/(?<=\w+\s*\((?:\s*\w+\s*,\s*)*\s*)\w+(?=\s*(?:\s*,\s*\w+\s*)*\))/g
Use this regular expression for getting the arguments:
const argsRegex = /\(\s*([^)]+?)\s*\)/
For getting the arguments in an array:
const str = 'walkPath(left, down, left)'
const argsRegex = /\(\s*([^)]+?)\s*\)/
let res = str.match(argsRegex)
let args = res[1].split(", ")

How to split string with multiple semi colons javascript

I have a string like below
var exampleString = "Name:Sivakumar ; Tadisetti;Country:India"
I want to split above string with semi colon, so want the array like
var result = [ "Name:Sivakumar ; Tadisetti", "Country:India" ]
But as the name contains another semi colon, I am getting array like
var result = [ "Name:Sivakumar ", "Tadisetti", "Country:India" ]
Here Sivakumar ; Tadisetti value of the key Name
I just wrote the code like exampleString.split(';')... other than this not able to get an idea to proceed further to get my desired output. Any suggestions?
Logic to split: I want to split the string as array with key:value pairs
Since .split accepts regular expressions as well, you can use a one that matches semicolons that are only followed by alphanumeric characters that end in : (in effect if they are followed by another key)
/;(?=\w+:)/
var exampleString = "Name:Sivakumar ; Tadisetti;Country:India";
var result = exampleString.split(/;(?=\w+:)/);
console.log(result)
here is an approach which we first split the input on ; and then concat the element without : with the previous one; since it shouldn't being spited.
let exampleString = "Name:Sivakumar ; Tadisetti;Country:India"
let reverseSplited = exampleString.split(";").reverse();
let prevoiusString;
let regex = /[^:]+:.*/;
let result = reverseSplited.map( str => {
if(regex.test(str)) {
if(prevoiusString){
let returnValue = str + ";" + prevoiusString;
prevoiusString = null;
return returnValue
}
return str
}
prevoiusString = str;
}).filter(e=>e);
console.log(result);

How to search strings with brackets using Regular expressions

I have a case wherein I want to search for all Hello (World) in an array. Hello (World) is coming from a variable and can change. I want to achieve this using RegExp and not indexOf or includes methods.
testArray = ['Hello (World', 'Hello (World)', 'hello (worlD)']
My match should return index 1 & 2 as answers.
Use the RegExp constructor after escaping the string (algorithm from this answer), and use some array methods:
const testArray = ['Hello (World', 'Hello (World)', 'hello (worlD)'];
const string = "Hello (World)".replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
const regex = new RegExp(string, "i");
const indexes = testArray.map((e, i) => e.match(regex) == null ? null : i).filter(e => e != null);
console.log(indexes);
This expression might help you to do so:
(\w+)\s\((\w+)
You may not need to bound it from left and right, since your input strings are well structured. You might just focus on your desired capturing groups, which I have assumed, each one is a single word, which you can simply modify that.
With a simple string replace you can match and capture both of them.
RegEx Descriptive Graph
This graph shows how the expression would work and you can visualize other expressions in this link:
Performance Test
This JavaScript snippet shows the performance of that expression using a simple 1-million times for loop.
repeat = 1000000;
start = Date.now();
for (var i = repeat; i >= 0; i--) {
var string = "Hello (World";
var regex = /(\w+)\s\((\w+)/g;
var match = string.replace(regex, "$1 & $2");
}
end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match 💚💚💚 ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. 😳 ");
testArray = ['Hello (World', 'Hello (World)', 'hello (worlD)'];
let indexes = [];
testArray.map((word,i)=>{
if(word.match(/\(.*\)/)){
indexes.push(i);
}
});
console.log(indexes);

Bold part of String

What is the best way to bold a part of string in Javascript?
I have an array of objects. Each object has a name. There is also an input parameter.
If, for example, you write "sa" in input, it automatically searches in array looking for objects with names that contain "sa" string.
When I print all the names, I want to bold the part of the name that coincide with the input text.
For example, if I search for "Ma":
Maria
Amaria
etc...
I need a solution that doesn't use jQuery. Help is appreciated.
PD: The final strings are in the tag. I create a list using angular ng-repeat.
This is the code:
$scope.users = data;
for (var i = data.length - 1; i >= 0; i--) {
data[i].name=data[i].name.replace($scope.modelCiudad,"<b>"+$scope.modelCiudad+"</b>");
};
ModelCiudad is the input text content var. And data is the array of objects.
In this code if for example ModelCiudad is "ma" the result of each is:
<b>Ma</b>ria
not Maria
You can use Javascript's str.replace() method, where str is equal to all of the text you want to search through.
var str = "Hello";
var substr = "el";
str.replace(substr, '<b>' + substr + '</b>');
The above will only replace the first instance of substr. If you want to handle replacing multiple substrings within a string, you have to use a regular expression with the g modifier.
function boldString(str, substr) {
var strRegExp = new RegExp(substr, 'g');
return str.replace(strRegExp, '<b>'+substr+'</b>');
}
In practice calling boldString would looks something like:
boldString("Hello, can you help me?", "el");
// Returns: H<b>el</b>lo can you h<b>el</b>p me?
Which when rendered by the browser will look something like: Hello can you help me?
Here is a JSFiddle with an example: https://jsfiddle.net/1rennp8r/3/
A concise ES6 solution could look something like this:
const boldString = (str, substr) => str.replace(RegExp(substr, 'g'), `<b>${substr}</b>`);
Where str is the string you want to modify, and substr is the substring to bold.
ES12 introduces a new string method str.replaceAll() which obviates the need for regex if replacing all occurrences at once. It's usage in this case would look something like this:
const boldString = (str, substr) => str.replaceAll(substr, `<b>${substr}</b>`);
I should mention that in order for these latter approaches to work, your environment must support ES6/ES12 (or use a tool like Babel to transpile).
Another important note is that all of these approaches are case sensitive.
Here's a pure JS solution that preserves the original case (ignoring the case of the query thus):
const boldQuery = (str, query) => {
const n = str.toUpperCase();
const q = query.toUpperCase();
const x = n.indexOf(q);
if (!q || x === -1) {
return str; // bail early
}
const l = q.length;
return str.substr(0, x) + '<b>' + str.substr(x, l) + '</b>' + str.substr(x + l);
}
Test:
boldQuery('Maria', 'mar'); // "<b>Mar</b>ia"
boldQuery('Almaria', 'Mar'); // "Al<b>mar</b>ia"
I ran into a similar problem today - except I wanted to match whole words and not substrings. so if const text = 'The quick brown foxes jumped' and const word = 'foxes' than I want the result to be 'The quick brown <strong>foxes</strong> jumped'; however if const word = 'fox', than I expect no change.
I ended up doing something similar to the following:
const pattern = `(\\s|\\b)(${word})(\\s|\\b)`;
const regexp = new RegExp(pattern, 'ig'); // ignore case (optional) and match all
const replaceMask = `$1<strong>$2</strong>$3`;
return text.replace(regexp, replaceMask);
First I get the exact word which is either before/after some whitespace or a word boundary, and then I replace it with the same whitespace (if any) and word, except the word is wrapped in a <strong> tag.
Here is a version I came up with if you want to style words or individual characters at their index in react/javascript.
replaceAt( yourArrayOfIndexes, yourString/orArrayOfStrings )
Working example: https://codesandbox.io/s/ov7zxp9mjq
function replaceAt(indexArray, [...string]) {
const replaceValue = i => string[i] = <b>{string[i]}</b>;
indexArray.forEach(replaceValue);
return string;
}
And here is another alternate method
function replaceAt(indexArray, [...string]) {
const startTag = '<b>';
const endTag = '</b>';
const tagLetter = i => string.splice(i, 1, startTag + string[i] + endTag);
indexArray.forEach(tagLetter);
return string.join('');
}
And another...
function replaceAt(indexArray, [...string]) {
for (let i = 0; i < indexArray.length; i++) {
string = Object.assign(string, {
[indexArray[i]]: <b>{string[indexArray[i]]}</b>
});
}
return string;
}
Above solutions are great, but are limited! Imagine a test scenerio where you want to match case insensitive query in a string and they could be multiple matches.
For example
Query: ma
String: The Amazing Spiderman
Expected Result: The Amazing Spiderman
For above scenerio, use this:
const boldMatchText = (text,searchInput) => {
let str = text.toLowerCase();
const query = searchInput.toLowerCase();
let result = "";
let queryLoc = str.indexOf(query);
if (queryLoc === -1) {
result += text;
} else
do {
result += ` ${text.substr(0, queryLoc)}
<b>${text.substr(queryLoc, query.length)}</b>`;
str = str.substr(queryLoc + query.length, str.length);
text = text.substr(queryLoc + query.length, str.length);
queryLoc = str.indexOf(query);
} while (text.length > 0 && queryLoc !== -1);
return result + text;
};

Categories

Resources