I have a string to search, and I need to match and return another string at the beginning of the search string. The string being searched may have whitespace in it, which needs to be ignored for the purpose of searching, but still returned accurately. The string to be matched will never have whitespace in it.
stringA = "ThisIsAString";
Should give the following results when compared to stringB:
stringB = "This Is A String"; //"This Is A String"
stringB = "ThisIsAlsoAString"; //undefined
stringB = "ThisIs A String With Extra Words At The End"; //"ThisIs A String"
stringB = "Hey, ThisIsAString"; //undefined
What's an efficient way to do this?
You can use \s* to match zero or more spaces. With the code below we put one of those matchers between each character.
const stringA = "ThisIsAString";
const tests = [
"This Is A String",
"ThisIsAlsoAString",
"ThisIs A String With Extra Words At The End",
"Hey, ThisIsAString",
];
const optionalSpaces = '\\s*';
const results = tests.map(test =>
test.match(
new RegExp(stringA.split('').join(optionalSpaces))
)
);
console.log(results);
An easy way to do this would be to remove all white space from the two things you are comparing.
var search = "Hello There";
var text = "HelloThere I'm Greg";
var found = text.replace(/ +?/g, '').indexOf(search.replace(/ +?/g, '')) !== -1;
Related
I am new to programming and I want to extract string from # character that is before cursor position until I find a whitespace.
what I am trying to do?
consider the string "hello from #us to you"
and the cursor position is at index 12 next to "#" now I want to extract string "us" which is after # character until whitespace.
This is what I have tried:
string1 = value.substr(0, event.target.selectionStart);
string2= string1.slice(string1.lastIndexOf('#') + 1);
string3 = string2.split(' ')[0];
But this gives me "" empty string.
how can I get a string "us" could someone help me with this. thanks:
You are very close. Take the remainder of the string like below with two approaches. The first operates on the string and the second operates on the array:
const cursorPosition = 6;
const str = "hello from #us to you";
const str1 = str.substring(cursorPosition);
const str2 = str1.substring(str1.lastIndexOf('#')+1).split(' ')[0];
console.log(str2)
//or
const out = str1.split(" ").find(word=>word.includes('#')).substring(1);
console.log(out);
similar to what you did:
"hello from #us to you".split('#')[1].split(' ')[0]
I have a string that has the following format: <strong>FirstName LastName</strong>
How can I change this into an array with the first element firstName and second lastName?
I did this, but no luck, it won't produce the right result:
var data = [myString.split('<strong>')[1], myString.split('<strong>')[2]]
How can I produce ["firstName", "lastName"] for any string with that format?
In order to parse HTML, use the best HTML parser out there, the DOM itself!
// create a random element, it doesn't have to be 'strong' (e.g., it could be 'div')
var parser = document.createElement('strong');
// set the innerHTML to your string
parser.innerHTML = "<strong>FirstName LastName</strong>";
// get the text inside the element ("FirstName LastName")
var fullName = parser.textContent;
// split it into an array, separated by the space in between FirstName and LastName
var data = fullName.split(" ");
// voila!
console.log(data);
EDIT
As #RobG pointed out, you could also explicitly use a DOM parser rather than that of an element:
var parser = new DOMParser();
var doc = parser.parseFromString("<strong>FirstName LastName</strong>", "text/html");
console.log(doc.body.textContent.split(" "));
However, both methods work perfectly fine; it all comes down to preference.
Just match everything between <strong> and </strong>.
var matches = "<strong>FirstName LastName</strong>".match(/<strong>(.*)<\/strong>/);
console.log(matches[1].split(' '));
The preferred approach would be to use DOM methods; create an element and get the .textContent then match one or more word characters or split space character.
let str = '<strong>FirstName LastName</strong>';
let [,first, last] = str.split(/<[/\w\s-]+>|\s/g);
console.log(first, last);
/<[/\w\s-]+>|\s/g
Splits < followed by one or more word, space or dash characters characters followed by > character or space to match space between words in the string.
Comma operator , within destructuring assignment is used to omit that index from the result of .split() ["", "FirstName", "LastName", ""].
this is my approach of doing your problem. Hope it helps!
var str = "<strong>FirstName LastName</strong>";
var result = str.slice(0, -9).substr(8).split(" ");
Edit: it will only work for this specific example.
Another way to do this in case you had something other than an html
var string = "<strong>FirstName LastName</strong>";
string = string.slice(0, -9); // remove last 9 chars
string = string.substr(8); // remove first 8 chars
string = string.split(" "); // split into an array at space
console.log(string);
for example i have this two strings:
string1:
"hi sir may name is Jone"
string2
"hi may name is Jone"
i have this this regex:
var regex = XRegExp('hi(?:(?!hi|Jone).)*?Jone', 'gs');
will match both of them but i want to modify the regex to match only in limited length of the whole string
i want to match the string two "hi may name is Jone" as had less words length how to do it..
If you want to get the string with the least amount of words that also matches your regex, you could split and use a whitespace as a separator and check the length of the returned array.
As an example with an array of strings, you could create var longestString = ""; which will at the end of the loop contain the shortest matched string.
In the loop, first check if there is a match and if longestString is an empty string. If that is the case then set the variable so you have a match to compare against future possible matches.
var strings = [
"test",
"hi sir may name is Jone",
"hi may name is Jone",
"hi Jone",
"hi may name is Jone test",
"hi i am Jone",
"may name is Jone test",
"hi may name is Jane test test 2"
];
var regex = /hi(?:(?!hi|Jone).)*?Jone/;
var longestString = "";
strings.forEach((str) => {
var match = XRegExp.match(str, regex);
if (match && longestString === "") {
longestString = str;
return;
}
if (match && str.split(" ").length < longestString.split(" ").length) {
longestString = str;
}
});
console.log(longestString);
<script src="https://unpkg.com/xregexp/xregexp-all.js"></script>
If you want to match a limited length of the whole string using only regex, I think you can do something like this:
var index = 15;
var testString1 = "hi may name is Jone";
var testString2 = "hi sir may name is Jone";
testString1.match("^.{1," + index + "}Jone"); // This will match
testString2.match("^.{1," + index + "}Jone"); // This string is longer and will not match
Explanation of the regex ^.{1, n}Jone.
^ : should match the start of the string.
.{1, n}Jone : matches everything between 1 to n until the pattern is fully matched.
In this case we define the n as index so this "limit" can be dynamic.
Hope this helps!
I am trying to match whole exact words using a javascript regular expression.
Given the strings: 1) "I know C++." and 2) "I know Java."
I have tried using new Regex('\\b' + text + '\\b', 'gi') and that works great for words without special characters like example #2.
I've also taken a look at this url:
Regular expression for matching exact word affect the special character matching
and implemented the:
escaped = escaped.replace(/^(\w)/, "\\b$1");
escaped = escaped.replace(/(\w)$/, "$1\\b");
and that will match text = 'C++' (it will match both examples)
However, if someone types a typo, and the string is "I know C++too.", the latter regex will still match the C++ when I don't want it to because the word "C++too" is not an exact match for text = 'C++'.
What changes can I make so that it will not match unless C++ is both the front of the word and the end of the word.
You can add a range of accepted characters([+#]) after word characters:
str = 'I know C++too. I know Java and C#.';
console.log(str.match(/(\w[+#]+|\w+)/g));
NB: \w[+#]+ must be placed first in the alternation expression to take precedence over the more generic \w+.
If whole words including special characters means everything but [\r\n\t\f\v ], you can simply do:
const REGEX = /([^\s]+)+/g;
function selectWords(string) {
const REGEX = /([^\s]+)+/g;
return string
// remove punctuation
.replace(/[^a-z0-9\s+#]/ig, "")
// perform the match
.match(REGEX)
// prevent null returns
|| []
;
}
var text = "Hello World"
var [first, second, ...rest] = selectWords(text);
console.log(1, {first, second, rest});
// example with punctuation
var text = "I can come today, she said, but not tomorrow."
var [first, second, third, ...rest] = selectWords(text);
console.log(2, {first, second, third, rest});
// example with possible throw
var text = ",.'\"` \r"
var [first, second, third, ...rest] = selectWords(text);
console.log(3, {first, second, third, rest});
// example with a specific word to be matched
function selectSpecificWord(string, ...words) {
return selectWords(string)
.filter(word => ~words.indexOf(word))
;
}
var expected = "C++";
var test = "I know C++";
var test1 = "I know C++AndJava";
console.log("Test Case 1", selectSpecificWord(test, expected));
console.log("Test Case 2", selectSpecificWord(test1, expected));
Use this ((?:(?:\w)+?)(?=\b|\w[-+]{2,2})(?:[-+]{2,2})?)
I've included a - symbol for an example also. See it in life.
Here is a codesample for the flag ignore case. I was expected to receive only one match.
var str = "Sample text";
var a = new Array();
a = str.match(/S(am)(p)/i);
result
a = [Samp] [am] [p]
I was expected to have a = [Samp]
if you change i flag with g
var str = "Sample text";
var a = new Array();
a = str.match(/S(am)(p)/g);
surprise (at least for me) the result has only one element
a = [Samp]
The javascript regex API is extremely unintuitive as it does all sorts of magic depending on the g-flag.
I am just gonna cover how .match behaves:
Without g-flag .match returns an array of full match plus all the capture groups or null in case of no match.
With g-flag .match returns an array of all the full matches and capture groups don't make a difference. null if there are no matches.
a = str.match(/S(am)(p)/i);
return first matched string, $1 $2
a = str.match(/S(am)(p)/g);
return array of matched (only one here)
if your string is decalred like that
var str = "Sample text Sample text";
/g return Samp Samp, it is usefull when your regexp looks like /S(.m)(p)/g and string looks like "Sample text Simple text";