Match Multiple validation on 1 input with javascript - javascript

I'd like to find a way to match the length of an input as well as the characters inside that input using javascript. Normally I'd just use the jquery plugin for validation, but for the client we can't use any 3rd party modules.
The input requires a string of characters between 6-13 but also does not allow the < or > characters within the values.
I'd like a way to check both the length of the string to make sure its between 6-13 but also reject the string if it contains < or >. I'm assuming this can be done with Regex, but my skills are severely lacking. The user should be able to see a message based on length and incorrect characters depending on what they are typing. Any quick methods out there?

or use this pattern
^(?!.*[<>]).{6,13}$
Demo
^ beginning of line
(?! Negative Look-Ahead
. Any character except line break
* (zero or more)(greedy)
[<>] Character Class [<>]
) End of Negative Look-Ahead
. Any character except line break
{6,13}$ (repeated {6,13} times) to the end

Related

Regex: Match every character between two strings

I am trying to find a way to match every character between two strings.
For example, for the given string abc--def--ghi, I want the regex to match d, e, and f.
I've tried using the following regex (?<=--)(.*)(?=--), however this matches all the characters between -- (def), whereas I need to match every character between --.
s.match(/--(.*?)--/)[1].split("") doesn't work as I need to do this without splitting.
Any suggestions?
In JavaScript, using the ECMAScript 2018+ compliant regex engine, you can achieve what you want without additional split step using
/(?<=--(?:(?!--).)*).(?=(?:(?!--).)*--)/gs
/(?<=--[^-]*(?:-(?!-)[^-]*)*).(?=[^-]*(?:-(?!-)[^-]*)*--)/gs
See the regex demo (the second variant is the same regex as the first one, but more efficient as it follows the "unroll-the-loop" principle). Details:
(?<=--(?:(?!--).)*) - a location immediately preceded by -- and then any one or more (as many as possible) chars, each of which does not start a -- char sequence
. - any single char
(?=(?:(?!--).)*--) - immediately followed by any one or more (as many as possible) chars, each of which does not start a -- char sequence, and then --.
The s flag enables . to match any char including line break chars that . does not match by default.

Javascript RegEx match 1-1-1 and 1-1-1-1-1 but not -1-1-1-1 or 1-1-1-1-

i haven't found anything when using google and stack overflow.
I need to match 1-1-1 but not -1-1-1 or 1-1-1- with javascript RegEx.
So it has to start with a number and end with a number and has to be seperated with "-".
I can't figure out, how to do it.
Is it even possible?
Unfortunately, JavaScript regex doesn't have a look-behind (see javascript regex - look behind alternative?), so to exclude a preceding -, the regex will have to match on the preceding character too (as long as it's not a -).
Since there might not be a preceding character (input starts with 1), you have to also match on beginning of input (^).
So, this regex will do it: (?:[^-]|^)(1(?:-1)+)(?!-)
See regex101.com.
Whether it should match a standalone 1, or only on 1-1 (and longer), is up to you. The regex above will not match standalone 1. Change + to * to change that.
I also added capturing of the actual text you wanted to match, i.e. without the leading character. You can remove the extra () around 1(?:-1)+ if that's not needed.

Regexp: excluding a word but including non-standard punctuation

I want to find strings that contain words in a particular order, allowing non-standard characters in between the words but excluding a particular word or symbol.
I'm using javascript's replace function to find all instances and put into an array.
So, I want select...from, with anything except 'from' in between the words. Or I can separate select...from from select...from (, as long as I exclude nesting. I think the answer is the same for both, i.e. how do I write: find x and not y within the same regexp?
From the internet, I feel this should work: /\bselect\b^(?!from).*\bfrom\b/gi but this finds no matches.
This works to find all select...from: /\bselect\b[0-9a-zA-Z#\(\)\[\]\s\.\*,%_+-]*?\bfrom\b/gi but modifying it to exclude the parenthesis "(" at the end prevents any matches: /\bselect\b[0-9a-zA-Z#\(\)\[\]\s\.\*,%_+-]*?\bfrom\b\s*^\(/gi
Can anyone tell me how to exclude words and symbols within this regexp?
Many thanks
Emma
Edit: partial string input:
left outer join [stage].[db].[table14] o on p.Project_id = o.project_id
left outer join
(
select
different_id
,sum(costs) - ( sum(brushes) + sum(carpets) + sum(fabric) + sum(other) + sum(chairs)+ sum(apples) ) as overallNumber
from
(
select ace from [stage].db.[table18] J
Javascript:
sequel = stringInputAsAbove;
var tst = sequel.replace(/\bselect\b[\s\S]*?\bfrom\b/gi, function(a,b) { console.log('match: '+a); selects.push(b); return a; });
console.log(selects);
Console.log(selects) should print an array of numbers, where each number is the starting character of a select...from. This works for the second regexp I gave in my info, printing: [95, 251]. Your \s\S variation does the same, #stribizhev.
The first example ^(?!from).* should do likewise but returns [].
The third example \s*^\( should return 251 only but returns []. However I have just noticed that the positive expression \s*\( does give 95, so some progress! It's the negatives I'm getting wrong.
Your \bselect\b^(?!from).*\bfrom\b regex doesn't work as expected because:
^ means here beginning of a line, not negation of next part, so
the \bselect\b^ means, select word followed by beginning of a
line. After removal of ^ regex start to match something
(DEMO) but it is still invalid.
in multiline text .* without modification will not match new line,
so regex will match only select...from in single lines, but if you
change it for (.|\n)* (as a simple example) it will match
multiline, but still invalid
the * is greede quantifire, so it will match as much a possible,
but if you use reluctant quantifire *?, regex will match to first
occurance of from word, and int will start to return relativly
correct result.
\bselect\b(?!from) means match separate select word which is not
directly followed by separate from word, so it would be
selectfrom somehow composed of separate words (because
select\bfrom) so (?!from) doesn't work and it is redundant
In effect you will get regex very similar to what Stribizhev gave you: \bselect\b(.|\n)*?\bfrom\b
In third expression you meke same mistake: \bselect\b[0-9a-zA-Z#\(\)\[\]\s\.\*,%_+-]*?\bfrom\b\s*^\( using ^ as (I assume) a negation, not beginning of a line. Remove ^ and you will again get relativly valid result (match from select through from to closing parathesis ) ).
Your second regex works similar to \bselect\b(.|\n)*?\bfrom\b or \bselect\b[\s\S]*?\bfrom\b.
I wrote "relativly valid result", as I also think, that parsing SQL with regex could be very camplicated, so I am not sure if it will work in every case.
You can also try to use positive lookahead to match just position in text, like:
(?=\bselect\b(?:.|\n)*?\bfrom\b)
DEMO - the () was added to regex just to return beginning index of match in groups, so it would be easier to check it validity
Negation in regex
We use ^ as negation in character class, for example [^a-z] means match anything but not letter, so it will match number, symbol, whitespace, etc, but not letter from range a to z (Look here). But this negation is on a level of single character. I you use [^from] it will prevent regex from matching characters f,r,o and m (demo). Also the [^from]{4} will avoid matching from but also form, morf, etc.
To exlude the whole word from matching by regex, you need to use negative look ahead, like (?!from), which will fail to match, if there will be chosen word from fallowing given position. To avoid matching whole line containing from you could use ^(?!.*from.*).+$ (demo).
However in your case, you don't need to use this construction, because if you replace greedy quantifire .*\bfrom with .*?\bfrom it will match to first occurance of this word. Whats more it would couse problems. Take a look on this regex, it will not match anything because (?![\s\S]*from[\s\S]*) is not restricted by anything, so it will match only if there is no from after select, but we want to match also from! in effect this regex try to match and exclude from at once, and fail. so the (?!.*word.*) construction works much better to exclude matching line with given word.
So what to do if we don't what to match a word in a fragment of a match? I think select\b([^f]|f(?!rom))*?\bfrom\b is a good solution. With ([^f]|f(?!rom))*? it will match everything between select and from, but will not exclude from.
But if you would like to match only select...from not followed by ( then it is good idea to use (?!\() like. But in your regex (multiline, use of (.|\n)*? or [\s\S]*? it will cause to match up to next select...from part, because reluctant quantifire will chenge a plece where it need to match to make whole regex . In my opinion, good solution would be to use again:
select\b([^f]|f(?!rom))*?\bfrom\b(?!\s*?\()
which will not overlap additional select..from and will not match if there is \( after select...from - check it here

Regular expression to check contains only

EDIT: Thank you all for your inputs. What ever you answered was right.But I thought I didnt explain it clear enough.
I want to check the input value while typing itself.If user is entering any other character that is not in the list the entered character should be rolled back.
(I am not concerning to check once the entire input is entered).
I want to validate a date input field which should contain only characters 0-9[digits], -(hyphen) , .(dot), and /(forward slash).Date may be like 22/02/1999 or 22.02.1999 or 22-02-1999.No validation need to be done on either occurrence or position. A plain validation is enough to check whether it has any other character than the above listed chars.
[I am not good at regular expressions.]
Here is what I thought should work but not.
var reg = new RegExp('[0-9]./-');
Here is jsfiddle.
Your expression only tests whether anywhere in the string, a digit is followed by any character (. is a meta character) and /-. For example, 5x/- or 42%/-foobar would match.
Instead, you want to put all the characters into the character class and test whether every single character in the string is one of them:
var reg = /^[0-9.\/-]+$/
^ matches the start of the string
[...] matches if the character is contained in the group (i.e. any digit, ., / or -).
The / has to be escaped because it also denotes the end of a regex literal.
- between two characters describes a range of characters (between them, e.g. 0-9 or a-z). If - is at the beginning or end it has no special meaning though and is literally interpreted as hyphen.
+ is a quantifier and means "one or more if the preceding pattern". This allows us (together with the anchors) to test whether every character of the string is in the character class.
$ matches the end of the string
Alternatively, you can check whether there is any character that is not one of the allowed ones:
var reg = /[^0-9.\/-]/;
The ^ at the beginning of the character class negates it. Here we don't have to test every character of the string, because the existence of only character is different already invalidates the string.
You can use it like so:
if (reg.test(str)) { // !reg.test(str) for the first expression
// str contains an invalid character
}
Try this:
([0-9]{2}[/\-.]){2}[0-9]{4}
If you are not concerned about the validity of the date, you can easily use the regex:
^[0-9]{1,2}[./-][0-9]{1,2}[./-][0-9]{4}$
The character class [./-] allows any one of the characters within the square brackets and the quantifiers allow for either 1 or 2 digit months and dates, while only 4 digit years.
You can also group the first few groups like so:
^([0-9]{1,2}[./-]){2}[0-9]{4}$
Updated your fiddle with the first regex.

Excluding $ in a regex in CF

I am working through some different form validation types and I am having trouble getting all the items on my wishlist to work.
My code for my cfinput is this (works the same as a regular form input and has some canned javascript validation)
<cfinput type="Text" name="negdays"
range="0,23"
pattern="^(([^0]{1})([0-9])*|(0{1}))?$"
message="Negative Days must be a number between 0 and 23"
required="No" width="2" >
This one should, and does, exclude everything I need except the $. I am having difficulty stopping the form from accepting the $.
Another example that is similar is this one where I want a range and to keep it numeric, so I mixed the validation types
<cfinput type="text" name="achamount"
validate = "range,numeric"
range = "0,99999"
message="ACH Amount must be a range from 0 - 99999 and numeric only" >
... and it works perfect - except for one problem: a $ is allowed.
So I thought maybe I could add to it with a regex like this:
<cfinput type="text" name="achamount"
validate = "range,numeric,regex"
range = "0,99999"
pattern="^\d"
message="ACH Amount must be a range from 0 - 99999 and numeric only" >
But my pattern is of course only to limiting it to numeric, which I am already doing. I need my pattern to exclude the dollar signs. But as a special character its not behaving like the other stuff I want to get rid of.
Any ideas or suggestions? Everything I have tried either does not work or breaks all the other validation on the page.
Solution: Matching Only Numbers
You don't need to specifically exclude $ - to only allow numeric digits, you simply need to ensure every character matches \d.
To do this, you need to anchor the start and end of the regex to the start and the end of the input, which is done with the regex metacharacters ^ and $ respectively. (If you ever need to use either of these characters as literals, prefix them with a backslash.)
So for an integer between 0 and 99999 you want:
^\d{1,5}$
Matching an integer between 0 and 23 works the same way thing, but the central part of the pattern needs to be complex, to ensure you don't get 24 or above:
^(?:[03-9]|1\d?|2[0-3]?)$
The three alternatives here are:
* [03-9] matches any single digit except 1 or 2.
* 1\d? matches 1, or 1 followed by any digit.
* 2[0-3]? matches 2, or 2 followed by any digit upto 3.
The (?:..) is to ensure the ^ and $ still apply to the entire string.
(Of course, you could also just use ^\d{1,2}$ then later check if it's less than 24.)
Bonus Info: Excluding Characters
As above, you don't need to do this in this case, but if you encounter a situation where you did need to exclude $, you could do it either using a negative character class:
^[^$]{1,5}$
Or using a negative lookahead:
^(?:(?!\$).){1,5}$
This latter one is a bit more complicated, but it allows more flexibility so is useful to be aware of.
A lookahead is another form of anchor (it matches at a position, but doesn't consume the characters it matches). When used against a item that has a quantifier (the {1,5} bit) attached, you need to group both items together for it to apply correctly. (i.e. If you only did (?!\$).{1,5} the negative lookahead would only be checked for the first character, not all five.)
Note that outside of a character class $ must be escaped as \$ to prevent it's special meaning of "end of string anchor". Inside a character class it is just a regular character.
(Hopefully this explanation is clear - let me know if further information or clarification would be useful.)
Your regex ^(([^0]{1})([0-9])*|(0{1}))?$ can be simplified quite a bit. It seems that you want either a single digit preceeded by a 0 or maximum 2 digits.
Try this: ^\d{2}$
What about adding the $ to a range of characters you don't allow?
pattern="[^$]"

Categories

Resources