Javascript: get username substring(s) beginning with # symbol - javascript

I'm looking for a good way to get one or more usernames preceded by a # symbol in a string.
Some example strings could be:
"#username this is just a test string"
"Blabla bla #username this is just a test string"
"Message for #username1, #username2 and #username_three: this is just a test string! - #username4"
Any solutions? I've not been able to find anything.

One occurrence
To match a single occurrence use a regular expression without any modifier and then get rid of the # using .substr(1):
const myString = "Hey #username this is a test string";
const username = myString.match(/#\w+/)[0].substr(1);
// This will be "username"
NOTE: the \w in the regular expression is equivalent to [A-Za-z0-9_].
Multiple occurrences
For more than one occurrence use a regular expression with the g modifier to match more than one string, then use the .map() method to remove the # characters at the beginning of each username using .substr(1) to throw away the first character:
const myString = "Hey #username1 and #Username_Two, this is just a test string! #username3";
const usernames = myString.match(/#\w+/g).map(x => x.substr(1));
// This will be ["username1", "Username_Two", "username3"]
NOTE: I am using the regular expression /#\w+/g since that usernames can contain only letters, numbers and underscores (at least on the most common sites, like Twitter etc).

Try regular expression:
var m = "#username This is just a test string".match(/#(.+?)\b/);
console.log(m); // ["#username", "username"]

The other answers work fine (mostly). I'm adding this as an alternative for matching multiple instances of usernames:
var str = "random #foo string #bar test #baz";
var usernames = str.split(/#(\w+)/).filter(function(_, i) { return i % 2; });
// [ "foo", "bar", "baz" ]
This works because if you place a capture group inside the pattern when you call .split, it will include that matched group in the result array. Then you just have to take every other array element.
Note also that .filter was added in ECMAScript 5.1, so it may not be supported in older browsers. If this is a concern, either use the polyfill technique described in the MDN article, or a simple for loop.

Just do:
var user = "#username";
var user2 = user.split("#")[1];

Related

How to include a variable and exclude numbers[0-9] and letters[a-zA-Z] in RegExp?

I have a code that generates a random letter based on the word and I have tried to create a RegExp code to turn all the letters from the word to '_' except the randomly generated letter from the word.
const word = "Apple is tasty"
const randomCharacter = word[Math.floor(Math.random() * word.length)]
regex = new RegExp(/[^${randomCharacter}&\/\\#,+()$~%.'":;*?<>{}\s]/gi)
hint = word.replace(regex,'_')
I want to change all the letters to '_' except the randomly generated word. The above code for some reason does not work and shows the result: A___e __ ta_t_ and I'm not able to figure out what to do.
The final result I want is something like this: A____ __ _a___
Is there a way with regex to change all the alphabets and numbers '/[^a-zA-Z0-9]/g' to '_' except the randomly generated letter?
I'm listing all the expressions I want to include on my above code because I'm not able to figure out a way to do include and exclude at the same time using the variable with regex.
You can't do string interpolation inside of a RegExp literal (/.../). Meaning your placeholder ${randomCharacter} will not evaluate to its value in the template, but is instead interpreted literally as the string "${randomCharacter}".
If you want to use template literals, initialize your regex variable with a RegExp constructor instead, like:
const regex = new RegExp(`[^${randomCharacter}&\\/\\\#,+()$~%.'":;*?<>{}\\s]`, "gi");
See the MDN RegExp documentation for an explanation on the differences between the literal notation and constructor function, most notably:
The constructor of the regular expression object [...] results in runtime compilation of the regular expression. Use the constructor function when [...] you don't know the pattern and obtain it from another source, such as user input.
/(?:[^A\s])/
test it on regex101
just replace A in [^A\s] with you character that you want to ommit from replacement
demo:
const word = "Apple is tasty";
const randomCharacter = 'a';//word[Math.floor(Math.random() * word.length)];
regex = new RegExp('(?:[^' + randomCharacter + '\\s])', 'gi');
hint = word.replaceAll(regex, '_');
console.log(hint)

JavaScript escape stars on regular expression

I am trying to get a serial number from a zigbee packet (i.e get from 702442500 *13*32*702442500#9).
So far, I've tried this:
test = "*#*0##*13*32*702442500#9##";
test.match("\*#\*0##\*13\*32\*(.*)#9##");
And this:
test.match("*#*0##*13*32*(.*)#9##");
With no luck. How do I get a valid regular expression that does what I want?
The below regex matches the number which has atleast three digits,
/([0-9][0-9][0-9]+)/
DEMO
If you want to extract the big number, you can use:
/\*#\*0##\*13\*32\*([^#]+)#9##/
Note that I use delimiters / that are needed to write a pattern in Javascript (without the regexp object syntax). When you use this syntax, (double)? quotes are not needed. I use [^#]+ instead of .* because it is more clear and more efficent for the regex engine.
The easiest way to grab that portion of the string would be to use
var regex = /(\*\d{3,}#)/g,
test = "*13*32*702442500#9";
var match = test.match(regex).slice(1,-1);
This captures a * followed by 3 or more \d (numbers) until it reaches an octothorpe. Using the global (/g) modifier will cause it to return an array of matches.
For example, if
var test = "*13*32*702442500#9
*#*0##*13*32*702442500#9##";
then, test.match(regex) will return ["*702442500#", "*702442500#"]. You can then slice the elements of this array:
var results = [],
test = "... above ... ",
regex = /(\*\d{3,}#)/g,
matches = test.match(regex);
matches.forEach(function (d) {
results.push(d.slice(1,-1));
})
// results : `["702442500", "702442500"]`

Match a string if it comes after certain string

I need a regular expression for JavaScript to match John (case insensitive) after Name:
I know how to do it, but I don't know how to get string from a different line like so (from a textarea):
Name
John
This is what I tried to do :: var str = /\s[a-zA-Z0-9](?= Name)/;
The logic: get a string with letter/numbers on a linespace followed by Name.
Then, I would use the .test(); method.
EDIT:
I tried to make the question more simple than it should have been. The thing I don't quite understand is how do I isolate "John" (really anything) on a new line followed by a specific string (in this case Name).
E.g., IF John comes after Name {dosomething} else{dosomethingelse}
Unfortunately, JavaScript doesn't support look-behinds. For something this simple, you can just match both parts of the string like this:
var str = /Name\s+([a-zA-Z0-9]+)/;
You then just have to extract the first capture group if you want to get John. For example:
"Name\n John".match(/Name\s+([a-zA-Z0-9]+)/)[1]; // John
However if you're just using .test, the capture group isn't necessary. For example:
var input = "Name\n John";
if (/Name\s+[a-zA-Z0-9]+/.test(input)) {
// dosomething
} else{
// dosomethingelse
}
Also, if you need to ensure that Name and John appear on separate lines with nothing but whitespace in between, you can use this pattern with the multi-line (m) flag.
var str = /Name\s*^\s*([a-zA-Z0-9]+)/m;
You do not need a lookahead here, simply place Name before the characters you want to match. And to enable case-insensitive matching, place the i modifier on the end of your regular expression.
var str = 'Name\n John'
var re = /Name\s+[a-z0-9]+/i
if (re.test(str)) {
// do something
} else {
// do something else
}
Use the String.match method if you want to extract the name from the string.
'Name\n John'.match(/Name\s+([a-z0-9]+)/i)[1];
The [1] here refers back to what was matched/captured in capturing group #1

Using regex to match part of a word or words

I'm new to regex and having difficulty with some basic stuff.
var name = "robert johnson";
var searchTerm = "robert johnson";
if (searchTerm.match(name)) {
console.log("MATCH");
}
I'd like to try and find something that matches any of the following:
rob, robert, john, johnson, robertjohnson
To make the regex simpler, I've already added a .toLowerCase() to both the "name" and the "searchTerm" vars.
What regex needs to be added to searchTerm.match(name) to make this work?
Clarification: I'm not just trying to get a test to pass with the 5 examples I gave, I'm trying to come up with some regex where any of those tests will pass. So, for example:
searchTerm.match(name)
...needs to change to something like:
searchTerm.match("someRegexVoodooHere"+name+"someMoreRegexVoodooHere")
So, if I edit
var searchTerm = "robert johnson";
...to be
var searchTerm = "rob";
...the same function searchTerm.match directive would work.
Again, I'm new to regex so I hope I'm asking this clearly. Basically I need to write a function that takes any searchTerm (it's not included here, but elsewhere I'm requiring that at least 3 characters be entered) and can check to see if those 3 letters are found, in sequence, in a given string of "firstname lastname".
"robert johnson".match(/\b(john(son)?|rob(ert(johnson)?)?)\b/)
Will give you all possible matches (there are more then one, if you need to find whether the input string contained any of the words.
/\b(john(son)?|rob(ert(johnson)?)?)\b/.test("robert johnson")
will return true if the string has any matches. (better to use this inside a condition, because you don't need to find all the matches).
\b - means word boundary.
() - capturing group.
? - quantifier "one or none".
| - logical "or".
You could create an array of the test terms and loop over that array. This method means less complicated regex to build in a dynamic environment
var name = "robert johnson";
var searchTerm = "robert johnson";
var tests = ['rob', 'robert', 'john', 'johnson', 'robertjohnson'];
var isMatch = false;
for (i = 0; i < tests.length; i++) {
if (searchTerm.test(tests[i])) {
isMatch = true;
}
}
alert(isMatch)
Regular expressions look for patterns to make a match. The answer to your question somewhat depends on what you are hoping to accomplish - That is, do you actually want matched groups or just to test for the existence of a pattern to execute other code.
To match the values in your string, you would need to use boolean OR matching with a | - using the i flag will cause a case insensitive match so you don't need to call toLowerCase() -
var regex = /(rob|robert|john|johnson|robertjohnson)/i;
regex.match(name);
If you want a more complex regex to match on all of these variations -
var names = "rob, robert, john, johnson, robertjohnson, paul";
var regex = /\b((rob(ert)?)?\s?(john(son)?)?)\b/i;
var matches = regex.match(names);
This will result in the matches array having 5 elements (each of the names except "paul"). Worth noting that this would match additional names as well, such as "rob johnson" and "rob john" which may not be desired.
You can also just test if your string contains any of those terms using test() -
var name = "rob johnson";
var regex = /\b((rob(ert)?)?\s?(john(son)?)?)\b/i;
if (regex.test(name)){
alert('matches!');
}
/^\s*(rob(ert)?|john(son)?|robert *johnson)\s*$/i.test(str)
will return true if str matches either:
rob
robert
john
johnson
robertjohnson
robert johnson
robert johnson (spaces between these 2 does not matter)
and it just doesn't care if there are preceding or following empty characters. If you don't want that, delete \s* from the beginning and the end of the pattern. Also, the space and asterisk between name and surname allows 0 or more spaces between those two. If you don't want it to contain any space, just get rid of that space and asterisk.
The caret ^ indicates beginning of string and the dollar sign $ indicates end of string. Finally, the i flag at the end makes it search case insensitively.

How to detect a series of characters in a string?

For example, I have a string:
"This is the ### example"
I would like to substring the ### out of the above string?
The number of Hash keys may vary, so I would like to find out and replace the ### pattern with, say, 001 for example.
Can anybody help?
You can also do a replace. I am familiar with the C# version of this,
string stringValue = "Thia is the ### example";
stringValue.Replace("###", "");
This would remove ### completely from the above string. Again you would have to know the exact string.
In JavaScript, it's similar - .replace (with a lowercase r) is used. So:
var stringValue = "This is the ### example";
var replacedValue = stringValue.replace('###', '');
You'll want to investigate either "Regular Expressions" for this, or, if you know the precise position and length of the characters you are interested in, you can simply use String's .substring method.
If you want to capture multiple # characters, then you'll need regular expressions:
var myString = "This is #### the example";
var result = myString.replace(/#+/g, '');
If you want to remove the space too, you can use the regex /#+\s|\s#+|#+/.
If the rest of the string is known, just get the part that you need:
var example = str.substr(12, str.length - 20);
The javascript match method will return an array of substrings matching a regular expression. You can use this to determine the number of matching characters to be replaced. Assuming you want to replace each octothorpe with a random digit, you could use code like this:
var exampleStr = "This is the ### example";
var swapThese = exampleStr.match(/#/g);
if (swapThese) {
for (var i=0;i<swapThese.length;i++) {
var swapThis = new RegExp(swapThese[i]);
exampleStr = exampleStr.replace(swapThis,Math.floor(Math.random()*9));
}
}
alert(exampleStr); // or whatever you want to do with it
Note that the code only loops the length of the array if it's present: if (swapThese) {
This check is necessary because if the match method finds no matches, it returns null rather than an empty array. Trying to iterate through null value will break.

Categories

Resources