I new to Regular Expressions in MVC DataAnnotations. I have a form that has a field named Option. The option must start with CA-.
I wrote the Regular Expression in different ways to validate this field and I can get it to work.
I tried all this:
[RegularExpression(#"^CA-")]
[RegularExpression(#"/CA-/")]
[RegularExpression(#"^[C]+[A]+[-]")]
[RegularExpression(#"^CA-*")]
none of this work.
What is wrong with my code?
Thank you.
public class CA_OptionsMetadata
{
[RegularExpression(#"^CA-", ErrorMessage = "The Option must start with CA-")]
[Required(ErrorMessage = "Option is Required")]
public string Option { get; set; }
//public string Cap_LBS { get; set; }
//public string Cap_KG { get; set; }
}
To match CA at the beginning of a string, use
#"^CA-.*$"
The main point is that the whole string should match (it is required by the RegularExpression), thus .*$ is important.
Regex explanation:
^ - start of string
CA- - a literal CA- sequence of characters
.* - zero or more characters other than a newline
$ - end of string
Related
I'm trying to evaluate a string against a set list of parameters with RegExp in Flutter. For example, the string must contain at least:
One capital letter
One lowercase letter
One number from 0-9
One special character, such as $ or !
This is basically for a password entry field of an application. I have set things up, firstly using validateStructure as follows:
abstract class PasswordValidator {
bool validateStructure(String value);
}
Then, I have used the RegExp function as follows:
class PasswordValidatorSpecial implements PasswordValidator {
bool validateStructure(String value) {
String pattern =
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~£]).{8,}$';
RegExp regEx = new RegExp(pattern);
return regEx.hasMatch(value);
}
}
This does work well, in a sense that when I pass a string/password through it, it does tell me if at least one of the criteria is not met. However, what I would like to do is for the output to be more specific, telling me which of those criteria isn't met.
For example, if the password were to have everything but a number (from 0-9) I would want to be able to get the output to specifically say that a number is missing, but everything else is present.
How would I adapt my code to be able to do that? I thought perhaps by using conditional 'if' statement, although I don't know how that would work. Thanks!
That's right, you can use RegExr to check your RegExp, separate each part and use them separately to have a custom error. Also instead of return a bool value, you can return a String value, such as the following function:
String validateStructure(String value) {
String patternUpperCaseCharacters = r'^(?=.*?[A-Z])';
String patternLowerCaseCharacters = r'^(?=.*?[a-z])';
String patternNumbers = r'^(?=.*?[0-9])';
String patternSpecialCharacters = r'^(?=.*?[!##\$&*~£])';
RegExp regEx = new RegExp(patternUpperCaseCharacters);
if (regEx.hasMatch(value)) {
regEx = new RegExp(patternLowerCaseCharacters);
if (regEx.hasMatch(value)) {
return "More errors";
} else {
return "You need at least one lowercase letter";
}
} else {
return "You need at least one capital letter";
}
}
Below is the regex which validates my passwords:
(((?=.*\\d{2,20})(?=.*[a-z]{2,20})(?=.*[A-Z]{3,20})(?=.*[##$%!##%&*?_~,-]{2,20})).{9,20}[^<>'\"])
Basically what I want is that it contains all above given characters in password. But it needs those characters in sequence e.g
it validates 23aaAAA#!, but it does not validatea2#!AAAa.
Simply add nested capturing groups to keep the chars validation not strictly as a sequence. The regex can be also simplified as follow (without extra groups):
(?=(?:.*[0-9]){2,20})
(?=(?:.*[a-z]){2,20})
(?=(?:.*[A-Z]){3,20})
(?=(?:.*[##$%!&*?_~,-]){2,20})
.{9,20}
[^<>'\"] # This matches also the newline char, i don't think you really want this...
In java use it as follows to match the :
String regex = "(?=(?:.*[0-9]){2,20})(?=(?:.*[a-z]){2,20})(?=(?:.*[A-Z]){3,20})(?=(?:.*[##$%!&*?_~,-]){2,20}).{9,20}[^<>'\"]";
String password = "23aaA#AA!#X"; // This have to be 10 chars long at least, no newline
if (password.matches(regex))
System.out.println("Success");
else
System.out.println("Failure");
The regex requires a password with (all not strictly in sequence):
(?=(?:.*[0-9]){2,20}): 2 numbers
(?=(?:.*[a-z]){2,20}): 3 lowercase lettes
(?=(?:.*[A-Z]){3,20}): 3 uppercase letters
(?=(?:.*[##$%!&*?_~,-]){2,20}): 2 of the symbols in the chars group
.{9,20}: Min length of 9 and max of 20
[^<>'\"]: One char that is not in (<,>,',") (NOTE: this matches also the newline)
So the min/max is actually 10/21 but the last statemente matches also the newline, so in the online regex demo, the visible chars will be between 9 and 20.
Regex online demo here
I would not try to build a single regexp, because nobody will ever be able to read nor change this expression ever again. It's to hard to understand.
"a2#!AAAa" will never validate because it needs 2 digits.
If you want a password, that contains a minmuum and maximum number of chars from a group. simply count them.
public class Constraint {
private Pattern pattern;
public String regexp = "";
public int mincount=2;
public int maxcount=6;
public Constraint(String regexp, int mincount, int maxcount) {
this.mincount=mincount;
this.maxcount=maxcount;
pattern = Pattern.compile(regexp);
}
public boolean fit(String str)
{
int count = str.length() - pattern.matcher(str).replaceAll("").length();
return count >= mincount && count <= maxcount;
}
#Override
public String toString() {
return pattern.toString();
}
}
public class Test {
static Constraint[] constraints = new Constraint[] {
new Constraint("[a-z]",2,20),
new Constraint("[A-Z]",2,20),
new Constraint("\\d",2,20),
new Constraint("["+Pattern.quote("##$%!##%&*?_~,-")+"]",2,20),
new Constraint("[<>'\\\"]",0,0)
};
public static boolean checkit(String pwd)
{
boolean ok=true;
for (Constraint constraint:constraints)
{
if (constraint.fit(pwd)==false)
{
System.out.println("match failed for constraint "+constraint);
ok=false;
}
}
return ok;
}
public static void main(String[] args) {
checkit("23aaAAA#!");
checkit("a2#!AAAa");
}
}
I am writing a parser using Flex and Bison and have defined various tokens as:
[0-9]+ { yylval.str=strdup(yytext); return digit; }
[0-9]+\.[0-9]* { yylval.str=strdup(yytext); return floating; }
[a-zA-Z_][a-zA-Z0-9_]* { yylval.str=strdup(yytext); return key; }
[a-zA-Z/][a-zA-Z_-/.]* { yylval.str=strdup(yytext); return string; }
[a-zA-Z0-9._-]+ { yylval.str=strdup(yytext); return hostname; }
["][a-zA-Z0-9!##$%^&*()_-+=.,/?]* { yylval.str=strdup(yytext); return qstring1; }
[a-zA-Z0-9!##$%^&*()_-+=.,/?]*["] { yylval.str=strdup(yytext); return qstring2; }
[#].+ { yylval.str=strdup(yytext); return comment;}
[ \n\t] {} /* Ignore white space. */
. {printf("ERR:L:%d\n", q); return ERROR;}
And it shows an error "Negative Range in Character Class" in the regexps for string, qstring1 and qstring2.
Can someone please help me with where I went wrong?
The spec is that:
Non quoted strings may contain ASCII alphanumeric characters, underscores, hyphens, forward slash and period and must start with letter or slash.
Quoted strings may contain any alphanumeric character between the quotes.
I have taken two different strings for quoted strings for some more specifications to be fulfilled.
Thanks.
For (string, qstring1, qstring2) you need to either place the hyphen (-) as the first or last character of your character class [] or just simply escape it \- if elsewhere.
(string)
[a-zA-Z/][a-zA-Z_./-]*
(qstring1)
["][a-zA-Z0-9!##$%^&*()_+=.,/?-]*
(qstring2)
[a-zA-Z0-9!##$%^&*()_+=.,/?-]*["]
- needs to be escaped with a backslash.
For qstring1, try the following:
["][a-zA-Z0-9!##$%^&*()_\-+=.,/?]*
I guess while writing a regular expression you should always write it with it's priority order :
for example for this line of code :
[+-/*><=] {printf("Operator %c\n",yytext[0]); return yytext[0];} won't give any error.
whereas :
[+-*/><=] {printf("Operator %c\n",yytext[0]); return yytext[0];} will.
hope it helps.
in java, I am trying to find if a given string has one of the many sub strings using multiple ORs in a single If condition and if any of the sub string exists, remove it. I am not sure how to do it. Also, this string search needs to be case insensitive.
Here is the sample code
if (inputString contains any of the subStrings i.e. "_LOCATION" OR "_MANAGEMENT" Or "_ZIPCODE")
{
remove the subString from inPutString
}
Ex: Given the string - "STATE_CAPITAL_LOCATION_MANAGEMENT_PHONE_EMAIL_zipcode"
Resulting string should be - "STATE_CAPITAL_PHONE_EMAIL"
What is the best way to do it.
Thanks
Using separate If statements makes more easier.
Try this code:
String a="STATE_CAPITAL_LOCATION_MANAGEMENT_PHONE_EMAIL_zipcode";
if(a.contains("_LOCATION"))// relace with your string
{
a=a.replace("_LOCATION","");
System.out.println(a);
}
if(a.contains("_MANAGEMENT"))// relace with your string
{
a=a.replace("_MANAGEMENT","");
System.out.println(a);
}
// .....
I have a regex call that I need help with.
I haven't posted my regex, because it is not relevant here.
What I want to be able to do is, during the Replace, I also want to modify the ${test} portion by doing a Html.Encode on the entire text that is effecting the regex.
Basically, wrap the entire text that is within the range of the regex with the bold tag, but also Html.Encode the text inbetween the bold tag.
RegexOptions regexOptions = RegexOptions.Compiled | RegexOptions.IgnoreCase;
text = Regex.Replace(text, regexBold, #"<b>${text}</b>", regexOptions);
There is an incredibly easy way of doing this (in .net). Its called a MatchEvaluator and it lets you do all sorts of cool find and replace. Essentially you just feed the Regex.Replace method the method name of a method that returns a string and takes in a Match object as its only parameter. Do whatever makes sense for your particular match (html encode) and the string you return will replace the entire text of the match in the input string.
Example: Lets say you wanted to find all the places where there are two numbers being added (in text) and you want to replace the expression with the actual number. You can't do that with a strict regex approach, but you can when you throw in a MatchEvaluator it becomes easy.
public void Stuff()
{
string pattern = #"(?<firstNumber>\d+)\s*(?<operator>[*+-/])\s*(?<secondNumber>\d+)";
string input = "something something 123 + 456 blah blah 100 - 55";
string output = Regex.Replace(input, pattern, MatchMath);
//output will be "something something 579 blah blah 45"
}
private static string MatchMath(Match match)
{
try
{
double first = double.Parse(match.Groups["firstNumber"].Value);
double second = double.Parse(match.Groups["secondNumber"].Value);
switch (match.Groups["operator"].Value)
{
case "*":
return (first * second).ToString();
case "+":
return (first + second).ToString();
case "-":
return (first - second).ToString();
case "/":
return (first / second).ToString();
}
}
catch { }
return "NaN";
}
Find out more at http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchevaluator.aspx
Don't use Regex.Replace in this case... use..
foreach(Match in Regex.Matches(...))
{
//do your stuff here
}
Heres an implementation of this I've used to pick out special replace strings from content and localize them.
protected string FindAndTranslateIn(string content)
{
return Regex.Replace(content, #"\{\^(.+?);(.+?)?}", new MatchEvaluator(TranslateHandler), RegexOptions.IgnoreCase);
}
public string TranslateHandler(Match m)
{
if (m.Success)
{
string key = m.Groups[1].Value;
key = FindAndTranslateIn(key);
string def = string.Empty;
if (m.Groups.Count > 2)
{
def = m.Groups[2].Value;
if(def.Length > 1)
{
def = FindAndTranslateIn(def);
}
}
if (group == null)
{
return Translate(key, def);
}
else
{
return Translate(key, group, def);
}
}
return string.Empty;
}
From the match evaluator delegate you return everything you want replaced, so where I have returns you would have bold tags and an encode call, mine also supports recursion, so a little over complicated for your needs, but you can just pare down the example for your needs.
This is equivalent to doing an iteration over the collection of matches and doing parts of the replace methods job. It just saves you some code, and you get to use a fancy shmancy delegate.
If you do a Regex.Match, the resulting match objects group at the 0th index, is the subset of the intput that matched the regex.
you can use this to stitch in the bold tags and encode it there.
Can you fill in the code inside {} to add the bold tag, and encode the text?
I'm confused as to how to apply the changes to the entire text block AND replace the section in the text variable at the end.