I'm new to JS, React and MUI, and I have a MUI TextField that should accept multiple values like
1*10 5*50 13*250 5*50 1*10
3*33.33 4*25 3*33.33
on a single line. The elements consist of a positive integers, asterisks and positive floating points/integers. What is the best way to approach this?
I have tried writing an onChange handler and a regex for pattern recognition.
const format = /[1-9]+[0-9]*\*[0-9]*[\.]?[0-9]*/g
This should match all possible values with no leading zeros and possible decimals after the multiplication asterisk. The numbers are arbitrary.
I can't wrap my head around how to disable user input/remove everything that doesn't match this pattern on the fly, since onChange changes the TextField value as soon as I press on a button.
Is there a way to mask this?
Are there better ways to do such input formatting?
If you want to match the whole string, going by the pattern you're trying to implement, I would do this
^(?:\d+\*\d*(?:\.\d*)? ?)*$
Here is a working example https://regex101.com/r/o8rvWH/1
If you watch to get the matching pattern you can do this
(\d+\*\d*(?:\.\d*)?)
Here is a working example https://regex101.com/r/OtfWIp/1
Here is my solution which includes most of your requisite.
The leading zero is not left out, but ruled out with regexp.
(\b[1-9]\d*\*(?:0\.(?=\S+[0-9])\d+|[1-9]\d*(?:\.\d+)?\b)(?= |$))+
example:
https://regex101.com/r/T9I7IV/1
I'm not familiar with javascript so you might need to change the \S.
Related
I'm trying to implement a username form validation in javascript where the username
can't start with numbers
can't have whitespaces
can't have any symbols but only One dot or One underscore or One dash
example of a valid username: the_user-one.123
example of invalid username: 1----- user
i've been trying to implement this for awhile but i couldn't figure out how to have only one of each allowed symbol:-
const usernameValidation = /(?=^[\w.-]+$)^\D/g
console.log(usernameValidation.test('1username')) //false
console.log(usernameValidation.test('username-One')) //true
How about using a negative lookahead at the start:
^(?!\d|.*?([_.-]).*\1)[\w.-]+$
This will check if the string
neither starts with digit
nor contains two [_.-] by use of capture and backreference
See this demo at regex101 (more explanation on the right side)
Preface: Due to my severe carelessness, I assumed the context was usage of the HTML pattern attribute instead of JavaScript input validation. I leave this answer here for posterity in case anyone really wants to do this with regex.
Although regex does have functionality to represent a pattern occuring consecutively within a certain number of times (via {<lower-bound>,<upper-bound>}), I'm not aware of regex having "elegant" functionality to enforce a set of patterns each occuring within a range of number of times but in any order and with other patterns possibly in between.
Some workarounds I can think of:
Make a regex that allows for one of each permutation of ordering of special characters (note: newlines added for readability):
^(?:
(?:(?:(?:[A-Za-z][A-Za-z0-9]*\.?)|\.)[A-Za-z0-9]*-?[A-Za-z0-9]*_?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*\.?)|\.)[A-Za-z0-9]*_?[A-Za-z0-9]*-?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*-?)|-)[A-Za-z0-9]*\.?[A-Za-z0-9]*_?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*-?)|-)[A-Za-z0-9]*_?[A-Za-z0-9]*\.?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*_?)|_)[A-Za-z0-9]*\.?[A-Za-z0-9]*-?)|
(?:(?:(?:[A-Za-z][A-Za-z0-9]*_?)|_)[A-Za-z0-9]*-?[A-Za-z0-9]*\.?)
)[A-Za-z0-9]*$
Note that the above regex can be simplified if you don't want usernames to start with special characters either.
Friendly reminder to also make sure you use the HTML attributes to enforce a minimum and maximum input character length where appropriate.
If you feel that regex isn't well suited to your use-case, know that you can do custom validation logic using javascript, which gives you much more control and can be much more readable compared to regex, but may require more lines of code to implement. Seeing the regex above, I would personally seriously consider the custom javascript route.
Note: I find https://regex101.com/ very helpful in learning, writing, and testing regex. Make sure to set the "flavour" to "JavaScript" in your case.
I have to admit that Bobble bubble's solution is the better fit. Here ia a comparison of the different cases:
console.log("Comparison between mine and Bobble Bubble's solution:\n\nusername mine,BobbleBubble");
["valid-usrId1","1nvalidUsrId","An0therVal1d-One","inva-lid.userId","anot-her.one","test.-case"].forEach(u=>console.log(u.padEnd(20," "),chck(u)));
function chck(s){
return [!!s.match(/^[a-zA-Z][a-zA-Z0-9._-]*$/) && ( s.match(/[._-]/g) || []).length<2, // mine
!!s.match(/^(?!\d|.*?([_.-]).*\1)[\w.-]+$/)].join(","); // Bobble bulle
}
The differences can be seen in the last three test cases.
I am trying to find a Regex for 1.5×10^9. Another value I have is 4.75×10^9
I have been able to make it work for 1.5×10^9 using /(\d.\d)×10\^(\d)/ but that doesn't work for 4.75×10^9.
Especially the first group is of decimal numbers & I'm not able to put Regex for decimal numbers inside the first parenthesis ().
How do I do it?
I want only 2 values: the first decimal value & the one after caret ^
Used Wiktor Stribizew's suggestion in the comments below:
/(\d+(?:\.\d+)?)×10\^(\d+)/ // matches 1.5×10^9 & 4.75×10^9
This works for my current use case but a more robust solution for decimal places can be found here
Never really used AngularJS and am having issues figuring out how to create a regex for an input to check/allow only first 2 characters to be letters & the rest numbers.
Hope this makes sense.
Using pugJS
.e-field
label.e-field__label(for='invoiceNr') Invoice Number
input#invoiceNumberInput.e-input(
ng-model='$ctrl.invoiceNumber'
name="invoiceNumber"
ng-required="true"
invoiceNr example: HN123123123
The ng-pattern was the answer. This is what I used:
ng-pattern="/^[a-zA-Z]{2}[0-9]{6,}$/"
Regex for first 2 character is number and rest is digits in angularJS input is as below. Use ng-pattern and the specified RegEX
ng-pattern="/^[a-zA-Z]{2}[0-9]*$/"
Not sure about the integration into Angular. However as a RegEx I think you could use this:
^[a-zA-Z]{2}[0-9]+$
(See test here)
...Just a quick comment regarding the use of ..[0-9]+$ as opposed to ...[0-9]*$
I think you should use + and not *. Otherwise a string like "HN" will also validate but I understood you only want to validate if it has numbers after the letters (like "HN1" or "HN123"..). For this case you should use "+".
I'm building an Ionic2 app and one of my text fields needs to be an emoji-only field.. to make my situation a little harder, the input field can only be 1 emoji long.
From what I know of emojis, some are considered 2 characters, and some are 1, which makes me wonder how I can force only 1 emoji length in a text input.
Is this possible? Essentially just a text field that only accepts 1 emoji..
Any feedback would be great. Thank you!
Since you haven't yet provided your own code I'm not going to answer your whole question.
You could start off by using a regular expression that only allows characters and then modify it using something like the emoji regex library provided below.
var val = "🐬";
if (val.match(/[^a-zA-Z]/g)) { // NOTE: will also match only characters
console.log(val);
} else {
console.log("Only characters allowed.")
}
You could also try a library like the following that's a regular expression to match all Emoji-only symbols as per the Unicode Standard. https://mths.be/emoji-regex
There's also a great article on Optimizing RegEx for Emoji.
I have been looking for a few hours how to do this particular regular expression magic with little to no luck.
I have been playing around with parsing some of my own medical data (why not?) which unfortunately comes in the form of a very unstructured text document with no tags (XML or HTML).
Specifically, as a prototype, I only want to match what my LDL delta (cholesterol change) is as a percentage.
In the form it shows up in a few different ways:
LDL change since last visit: 10%
or
LDL change since last visit:
10%
or
LDL change since last visit:
10%
I have been trying to do this in JavaScript using the native RegExp engine for a few hours (more than I want to admit) with little success. I am by no means a RegExp expert but I have been looking at an expression like such:
(?<=LDL change since last visit)*(0*(100\.00|[0-9]?[0-9]\.[0-9]{0,2})%)
Which I know does not work in JS because the lack support for ?<=. I tested these in Ruby but even then they were not successful. Could anybody work me through some ways of doing this?
EDIT:
Since this particular metric shows up a few times in different areas, I would like the regex to match them all and have them be accessible in multiple groups. Say matching group 0 corresponds to the Lipid Profile section and matching group 1 corresponds to the Summary.
Lipid profile
...
LDL change since last visit:
10%
...
Summary of Important Metrics
...
LDL change since last visit: 10%
...
A lookbehind solution is complicated because most languages only support fixed or finite length lookbehind assertions. Therefore it's easier to use a capturing group instead. (Also, the * quantifier after the lookbehind that you used makes no sense).
And since you don't really need to validate the number (right?), I would simply do
regexp = /LDL change since last visit:\s*([\d.]+)%/
match = regexp.match(subject)
if match
match = match[1]
else
match = nil
end
If you expect multiple matches per string, use .scan():
subject.scan(/LDL change since last visit:\s*([\d.]+)%/)