AngularJS: regex matching everything except strings with specific symbols weird behaviour [duplicate] - javascript

This question already has answers here:
AngularJS - Remove leading and trailing whitespace from input-box using regex
(2 answers)
Closed 7 years ago.
I am not very good at regular expressions so maybe this is a simple question, but I am certainly missing something. I use regular expressions to validate specific input from user. The input must be accepted (regex must match) if and only if the input string contains no commas and no whitespaces(in other words, the input must be single word without commas). Except that, it can contain any symbols and the input string can have any length. Now, when I use this regular expression, it matches input, that doesn't contain commas.
/^[^,]*$/
I wanted to add the whitespace part to it, so I made this expression
/^[^,\s]*$/
which behaves in a very weird way. It does what it should except one thing. For some reasons, it matches(and lets in) strings, that end with space (If they end with comma, everything is OK and it doesn't match). I dont wan't it to match strings with trailing whitespaces but I don't know, how to adjust the regular expression to do this. So my questions are - why is this weird thing happening and how to change the regular expression to do what it should.
here is an example:
http://jsbin.com/qoyoyagilo/2/edit?html,js,output
What is even weirder, when I tried my regex on rubular, it didn' t match strings with trailing whitespaces. I am starting to believe, that this has to do something with javascript and not with my particular regex

Angular already trims your strings before validating them and binding to model. Extra whitespace at the beginning and at the end of strings won't even be matched against your regular expression (or any other validator).
You can use ng-trim="false" if you wish to disable this behavior:
<input ng-model="yourmodelvar" ng-trim="false" ng-pattern="[^,\s]*">
Also note that you don't need the ^ and $ chars in your regexp, since validation is performed against the whole string automatically. From the documentation on ng-pattern:
Sets pattern validation error key if the ngModel $viewValue value does
not match a RegExp found by evaluating the Angular expression given in
the attribute value. If the expression evaluates to a RegExp object,
then this is used directly. If the expression evaluates to a string,
then it will be converted to a RegExp after wrapping it in ^ and $
characters. For instance, "abc" will be converted to new
RegExp('^abc$').
References:
https://docs.angularjs.org/api/ng/directive/input (official doc)
How to disable trimming of inputs in AngularJS?

Related

RegEx if then else for conditional test depending on first character [duplicate]

This question already has answers here:
How do I make part of a regex match optional?
(2 answers)
Closed 1 year ago.
I should allow 2 different input strings formats, with each their own validation.
So eg:
AA2222222222222222
and
2222222222222222
This means that if the first character is a letter, I should validate for ^[a-zA-Z]{2}\d{16}$. If the first character is numeric, I should validate for d{16}.
I tried to write it in an conditional regex:
^(([a-zA-Z])(?([a-zA-Z])^[a-zA-Z]{2}\d{16}$|d{16})
but I get a pattern error and can't figure out what exactly is wrong.
Any insight would be apreciated
I tried to write it in an conditional regex
JavaScript doesn't support regular expression conditional syntax, so (?ifthen|else) doesn't work in JavaScript.
This means that if the first character is a letter, I should validate for ^[a-zA-Z]{2}\d{16}$. If the first character is numeric, I should validate for d{16}.
Since the \d{16} part is the same, you can just make the [a-zA-Z]{2} part optional:
/^(?:[a-zA-Z]{2})?\d{16}$/
That uses a non-capturing group around the [a-zA-Z]{2} and makes the entire group optional via the ? after it.
If the validation were different (say, maybe the version with the letters at the start only does \d{14}), you could use an alternation:
/^(?:[a-zA-Z]{2}\d{14}|\d{16})$/
(Beware the gotcha: Without the non-capturing around around the alternation, the ^ would be part of the first alternative but not the second, and the $ would be part of the second alternative, but not the first.)
But in your specific case, you don't need that.

Regex get last 2 characters pipe not working

I'm creating a regex expression to get the variables passed to a JavaScript constructor.
The input is always going to follow along these lines:
app.use(express.static('public'));
And the regex I plan to use to strip out the unnecessary parts is:
(^app.use\()|(..$)
The first part of the regex gets everything up to the first parenthesis, and the it's supposed to pipe it to another expression which gets the last 2 characters of the string.
My issue is that it seems to be ignoring the second regex. I tried a few other expressions in the second part and they worked, but this one isn't.
What am I doing wrong?
Regex example on Regex101: https://regex101.com/r/jV9eH6/3
UPDATE:
This is not a duplicate of How to replace all occurrences of a string in JavaScript?
My question is about a specific issue with a regex, not about replacing one string with another in JavaScript.
You need to use multiline modifier. Whenever anchors ^, $ are used in your regex then feel free to add multi-line modifier m.
/(^app.use\()|(..$)/gm
DEMO

Javascript Regular Expression (exp)? issues

I have written a Javascript regular expression as below
/^(\[)(\d{1,2}([-]\d{1,2})?[,])*(\])$/
I am trying to validate against input text [21] but it fails. I am verifying using http://www.regexplanet.com/advanced/javascript/index.html
I am suspecting an issue with ([-]\d{1,2})?
Inputs that should pass are [12-23] or [34] or [12-23,34]
Please help
Your regular expression includes the part [,] which translates as "must contain a comma in that position".
If the comma is indeed required then [21] will not evaluate but [21,] will.
If the comma should have been optional that part of the expression should have been [,]? which makes in zero or one repetition, or perhaps [,]* which is any number of repetitions.
Final working expression was ^(\[)(\d{1,2}([-]\d{1,2})?[,]?)*(\])$ which passes on all of your expected inputs.
Enhancement - As noted in comments, your wrapping a single character in square braces, indicating a class of characters. This is not necessary when your class of characters has just one character, and makes a hard-to-read syntax like regexp even harder. Your expression can be shortened to ^(\[)(\d{1,2}(-\d{1,2})?,?)*(\])$

Negate random regular expression

Is there a way to negate any regular expression? I'm using regular expressions to validate input on a form. I'm now trying to create a button that sanitizes my input. Is there a way so I can use the regular expression used for the validating also for stripping the invalid characters?
I'm using this regex for validation of illegal characters
<input data-val-regex-pattern="[^|<>:\?'\*\[\]\=%\$\+,;~&\{\}]*" type="text" />
When clicking on a button next to it, I'm calling this function:
$('#button').click(function () {
var inputElement = $(this).prev();
var regex = new RegExp(inputElement.attr('data-val-regex-pattern'), 'g');
var value = inputElement.val();
inputElement.val(value.replace(regex, ''));
});
At the moment the javascript is doing the exact opposite of what I'm trying to accomplish. I need to find a way to 'reverse' the regex.
Edit: I'm trying to reverse the regex in the javascript function. The regex in the data-val-regex-pattern-attribute is doing his job for validation.
To find the invalid characters, just take the ^ off from your regex. The carret is the negative of everything that is inside the brackets.
data-val-regex-pattern="[|<>:\?'\*\[\]\=%\$\+,;~&\{\}]*"
This will return the undesired characters so you can replace them.
Also, as you want to take off a lot of non-word characters, you could try a simpler regex. If you want only word characters and spaces, you could use something like this:
data-val-regex-pattern="[\W\S]*"
Your reges is as so:
[^|<>:\?'\*\[\]\=%\$\+,;~&\{\}]*
That means, it matches any non-invalid character multiple times.
Then you replace this for empty, so you leave only the bad characters.
Try this instead, without the negation (hat moved somewhere else):
[|^<>:\?'\*\[\]\=%\$\+,;~&\{\}]*
The following answer is to the general question of negating a regular expression. In your specific case you just need to negate a character group, or more precisely remove the negation of a character group - which is detailed in other answers.
Regular languages – those consisting of all strings entirely by matched some RE – are in fact closed under negation: there is another RE which matches exactly those strings the original RE does not. It is however not trivial to construct, which perhaps explains why RE implementations often do not offer a negation operator.
However the Javascript regexp language has extensions that make it more expressive than regular languages; in particular there is the construct of negative lookahead.
If R1 is a regexp then
^(?!.*(R1))
matches precisely the strings that does not contain a match for R1.
And
^(?!R1$)
matches precisely the strings where the whole string is not a match for R1.
Ie. negation.
For rewriting any substring not matching a given regexp, the above is insufficient. One would have to do something like
((?!R1).)*
Which would catch any substring not containing a subsubstring that matches R1. - But consideration of the edge cases show that this does not quite do what we are after. For example ((?!ab).)* matches "b" in "ab", because "ab" is not a substring of "b".
One can cheat, and make your regexp like;
(.*)(R1|$)
And rewrite to T1$2
Where T1 is the target string you want to rewrite to.
This should rewrite any portion of the string not matching R1 to T1. However I would be very careful about any edge cases for this. So much so that it might be better to write the regexp from scratch rather than trying a general approach.

Specifying complex conditions in regular expressions

The id attribute values in HTML 5 has the following rules
1.The string should contain nonwhitespace characters
2. It should contain at least one letter
How can i represent this in regular expression form.I reached in a regular expression which satisfies the first condition..
/(^|\s)\S+/ig
But how can i indicate the second condition in to the above regular expression
...and I am new to regular expressions...
You have got your restrictions wrong. The HTML5 ID data type must:
must be at least one character long
must not contain any space characters
That's:
^\S+$
Done.
Note:
Without any characters in your regex (\S is not a character), you don't have to make your regex case-insensitive (/.../i is superfluous).
Since your regex is anchored (^...$) there can only ever be a single match. This means there is no need for the "global" modifier, so /.../g is superfluous as well.
The easiest way would be to match on two expressions.
myString.match(/(^|\s)\S+/i) && myString.match(/[a-zA-Z]/)

Categories