Validations.pattern doesn't work with Regex - regex

I have reactive form and one of the controls should be validated with the pattern .*[^\s].*. In case it is used in template-driven forms, it works well. But in a case of reactive - does not. What should I change to fix it?
this._form = this._formBuilder.group({
description: ['', [Validators.required, Validators.pattern('.*[^\S].*')]]
}

Have a look at the Validator.js:
/**
* Validator that requires a control to match a regex to its value.
*/
static pattern(pattern: string|RegExp): ValidatorFn {
if (!pattern) return Validators.nullValidator;
let regex: RegExp;
let regexStr: string;
if (typeof pattern === 'string') {
regexStr = `^${pattern}$`;
regex = new RegExp(regexStr);
} else {
regexStr = pattern.toString();
regex = pattern;
}
return (control: AbstractControl): {[key: string]: any} => {
if (isEmptyInputValue(control.value)) {
return null; // don't validate empty values to allow optional controls
}
const value: string = control.value;
return regex.test(value) ? null :
{'pattern': {'requiredPattern': regexStr, 'actualValue': value}};
};
}
The point is that the regex pattern is passed either like a regex literal, or as a string literal. When you pass it as a regex literal, you may use
/\S*\s.*/
It will be "converted" to a string with pattern.toString() and ^ and $ will be added - "^\\S*\\s.*$". This is exactly a string pattern you may pass in the Validators.Pattern, too.
Note that ^\S*\s.*$ will match a string that starts with 0+ non-whitespace chars, then has 1 obligatory whitespace, and then has any 0+ chars other than line break chars. It is a bit faster than /^.*\s.*$/. Note that \s = [^\S].

Related

Flutter how to validate password input field with regex

I use regex validation in my custom textfield listener, to check if password valid
this is my validation code
RegExp regexUpper = RegExp(r'^(?=.*[A-Z])$');
RegExp regexLower = RegExp(r'^(?=.*[a-z])$');
RegExp regexLength = RegExp(r'^.{8,}$');
if (!regexLength.hasMatch(value.toString())) {
return 'Пароль слишком короткий';
}
if (!regexLower.hasMatch(value.toString())) {
print(value);
return 'Пароль должен содержать хотя бы одну маленькую букву';
}
if (!regexUpper.hasMatch(value.toString())) {
return 'Введите хотя бы одну заглавную букву';
}
return null;
regexLength work correctly but other not.
What i did wrong and how i can fix it ?
You should not use lookarounds wrapped with anchors.
You can fix the issues with
RegExp regexUpper = RegExp(r'[A-Z]');
RegExp regexLower = RegExp(r'[a-z]');
RegExp regexLength = RegExp(r'^.{8,}$');
Look: ^(?=.*[A-Z])$ asserts the current position at the start of string (^), then checks if there is an uppercase ASCII letter ([A-Z]) anywhere after zero or more chars other than line break chars (as many as possible, with .*), and then requires the end of string ($) (right at the start of string). This is an example of a pattern that never matches any string.

scala regex meaning

i am new to scala and hate regex :D
cuurently i am debuggig a piece of code
def validateReslutions(reslutions: String): Unit = {
val regex = "(\\d+-\\d+[d,w,m,h,y],?)*"
if (!reslutions.matches(regex)) {
throw new Error("no match")
} else {
print("matched")
}
}
validateReslutions(reslutions = "(20-1w,100-1w)")
}
the problem is it produces no match for this input , so how to correct the regex to match this input
Your (20-1w,100-1w) string contains a pair of parentheses at the start and end, and the rest matches with your (\d+-\d+[d,w,m,h,y],?)* regex. Since String#matches requires a full string match, you get an exception.
Include the parentheses patterns to the regex to avoid the exception:
def validateReslutions(reslutions: String): Unit = {
val regex = """\((\d+-\d+[dwmhy],?)*\)"""
if (!reslutions.matches(regex)) {
throw new Error("no match")
} else {
print("matched")
}
}
validateReslutions(reslutions = "(20-1w,100-1w)")
// => matched
See the Scala demo.
Note the triple quotes used to define the string literal, inside which you can use single backslashes to define literal backslash chars.
Also, mind the absence of commas in the character class, they match literal commas in the text, they do not mean "or" inside character classes.

regex to extract substring for special cases

I have a scenario where i want to extract some substring based on following condition.
search for any pattern myvalue=123& , extract myvalue=123
If the "myvalue" present at end of the line without "&", extract myvalue=123
for ex:
The string is abcdmyvalue=123&xyz => the it should return myvalue=123
The string is abcdmyvalue=123 => the it should return myvalue=123
for first scenario it is working for me with following regex - myvalue=(.?(?=[&,""]))
I am looking for how to modify this regex to include my second scenario as well. I am using https://regex101.com/ to test this.
Thanks in Advace!
Some notes about the pattern that you tried
if you want to only match, you can omit the capture group
e* matches 0+ times an e char
the part .*?(?=[&,""]) matches as least chars until it can assert eiter & , or " to the right, so the positive lookahead expects a single char to the right to be present
You could shorten the pattern to a match only, using a negated character class that matches 0+ times any character except a whitespace char or &
myvalue=[^&\s]*
Regex demo
function regex(data) {
var test = data.match(/=(.*)&/);
if (test === null) {
return data.split('=')[1]
} else {
return test[1]
}
}
console.log(regex('abcdmyvalue=123&3e')); //123
console.log(regex('abcdmyvalue=123')); //123
here is your working code if there is no & at end of string it will have null and will go else block there we can simply split the string and get the value, If & is present at the end of string then regex will simply extract the value between = and &
if you want to use existing regex then you can do it like that
var test = data1.match(/=(.*)&|=(.*)/)
const result = test[1] ? test[1] : test[2];
console.log(result);

Match anything before certain character

I have the following strings
/search?checkin=2018-10-25&checkout=2018-10-27&id=bandung-108001534490276290&page=1&room=1&sort=popularity&type=CITY
/search?checkin=2018-12-09&checkout=2018-12-13&id=singapore-108001534490299035&maxPrice=&minPrice=&room=1&type=REGION
/search?checkin=2018-10-22&checkout=2018-10-23&lat=-6.1176043&long=106.7767146&maxPrice=&minPrice=&room=1&type=COORDINATE
/search?page=1&room=1&type=POI&id=taman-mini-indonesia-indah-110001539700828313&checkin=2018-11-14&checkout=2018-11-16&sort=distance
i want to get all string starts from &id= until the first & so they will return
id=bandung-108001534490276290
id=singapore-108001534490299035
id=taman-mini-indonesia-indah-110001539700828313
When i tried this regex \&id=.*\& it doesn't match my requirement.
Hown do i resolve this?
I'd go with [?&](id=[^&]+).
[?&] - ? or &, because order of GET parameters is usually not guaranteed and you can get the id in the first place – something like /search?id=something-123456&checkin=2018-10-25&…
[^&]+ - at least one character that's not &
() marks a capturing group
Demo in JS:
const strings = [
"/search?checkin=2018-10-25&checkout=2018-10-27&id=bandung-108001534490276290&page=1&room=1&sort=popularity&type=CITY",
"/search?checkin=2018-12-09&checkout=2018-12-13&id=singapore-108001534490299035&maxPrice=&minPrice=&room=1&type=REGION",
"/search?checkin=2018-10-22&checkout=2018-10-23&lat=-6.1176043&long=106.7767146&maxPrice=&minPrice=&room=1&type=COORDINATE",
"/search?page=1&room=1&type=POI&id=taman-mini-indonesia-indah-110001539700828313&checkin=2018-11-14&checkout=2018-11-16&sort=distance]"
]
const regex = /[?&](id=[^&]+)/
strings.forEach(string => {
const match = regex.exec(string)
if (match) {
console.log(match[1])
}
})
Demo and explanation at Regex101: https://regex101.com/r/FBeNDN/1/
Positive Lookahead (?=)
Try a positive lookahead:
/&id=.+?(?=&)|&id=.+?$/gm
This part: (?=&) means: if an & is found, then everything before it is a match.
The alternation:| (it's an OR logic gate) is an update in regards to a comment from Nick concerning that if the parameter ended with an &id=...
It's the same match but instead of looking for a & it will look for the end of the line $. Note that the multi-line flag is used to make $ represent EOL.
Demo
var str = `/search?checkin=2018-10-25&checkout=2018-10-27&id=bandung-108001534490276290&page=1&room=1&sort=popularity&type=CITY
/search?checkin=2018-12-09&checkout=2018-12-13&id=singapore-108001534490299035&maxPrice=&minPrice=&room=1&type=REGION
/search?page=1&room=1&type=POI&id=indo-1999999051158
/search?checkin=2018-10-22&checkout=2018-10-23&lat=-6.1176043&long=106.7767146&maxPrice=&minPrice=&room=1&type=COORDINATE
/search?page=1&room=1&type=POI&id=taman-mini-indonesia-indah-110001539700828313&checkin=2018-11-14&checkout=2018-11-16&sort=distance
/search?page=1&room=1&type=POI&id=indonesia-1100055689`;
var rgx = /&id=.+?(?=&$)|&id=.+?$/gm;
var res = rgx.exec(str);
while (res != null) {
console.log(res[0]);
res = rgx.exec(str);
}

Extracting user-defined Groovy tokens from strings

Groovy here : I need to scan a string for a substring of the form:
${token}:<someValue>]
That is:
A user-define (dynamic) token string (could be anything at runtime); then
A colon (:); then
Anything (<someValue>); then finally
A right squre bracket (])
So basically something like:
def String fetchTokenValue(String toScan, String token) {
if(toScan.matches(".*${token}:.*]")) {
String everythingBetweenColonAndRBracket = ???
return everythingBetweenColonAndRBracket
} else {
return 'NO_DICE'
}
}
Such that the output would be as follows:
fetchTokenValue('swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko', 'blah') => 'fizzbuzz'
fetchTokenValue('swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko', 'boo') => 'NO_DICE'
I'm struggling with the regex as well as how to, if a match is made, extract all the text between the colon and the right square bracket. We can assume there will only ever be one match, or simply operate on the first match that is found (if it exists).
Any ideas where I'm going awry?
You may use [^\]]* subpattern (a negated character class [^...] that matches any chars other than those defined inside it) to match zero or more chars other than ] and use a capturing group to capture that text and only return Group 1 contents. Also, it is a good idea to automatically escape the input token so as to avoid illegal pattern syntax issues:
import java.util.regex.*;
def String fetchTokenValue(String toScan, String token) {
def matcher = ( toScan =~ /.*${Pattern.quote(token)}:([^\]]*)].*/ )
if(matcher.matches()) {
return matcher.group(1)
} else {
return 'NO_DICE'
}
}
println fetchTokenValue('swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko', 'blah')
See the online Groovy demo
You could use this regex which grabs anything up to a ] into a group
def String fetchTokenValue(String toScan, String token) {
def match = toScan =~ /.+${token}:([^\]]+)/
if(match) { match[0][1] } else { 'NO_DICE' }
}
def str = 'swkokd sw:defroko swodjejr blah:fizzbuzz] wdkerko'
assert fetchTokenValue(str, 'blah') == 'fizzbuzz'
assert fetchTokenValue(str, 'boo') == 'NO_DICE'