Regex c#: Last Name in an email to include only one hyphen - c#

Friends,
I have a textbox, which takes firstname.Lastname for my organisation.
The last name may or may not include hyphen.If it includes, then it should appear,
1) Only once in last name
2) Not at the beginning of lastname
3) not at the end of last name
I have this Regex figured out
^(?!.{51})[a-zA-Z]+(?:[.][a-zA-Z-]+)?$
This includes "-" in last name. But will not satisfy above conditions.
Im still learning regex, and is taking time to figure out this.
Please help
-Thank you

You need to add one more nested group inside the last name part:
^(?!.{51})[a-zA-Z]+(?:\.[a-zA-Z]+(?:-[a-zA-Z]+)?)?$
^^^^^^^^^^^^^^^
See the regex demo
Details:
^ - start of string
(?!.{51}) - no more than 50 chars in the string requirement
[a-zA-Z]+ - 1+ ASCII letters
(?:\.[a-zA-Z]+(?:-[a-zA-Z]+)?)? - an optional sequence of:
\. - a dot
[a-zA-Z]+ - 1 or more ASCII letters
(?:-[a-zA-Z]+)? - an optional sequence of:
- - a hyphen
[a-zA-Z]+ - 1+ ASCII letters
$ - end of string.
To declare this pattern, use a verbatim string literal:
var pattern = #"^(?!.{51})[a-zA-Z]+(?:\.[a-zA-Z]+(?:-[a-zA-Z]+)?)?$";
To match any Unicode letters, use \p{L} instead of [a-zA-Z].

This is a somehow Quick and Dirty Solution.
^(?!.{51})[a-zA-Z]+.{1}[a-zA-Z]{1,}-?[a-zA-Z]+$
The first part of the string is still used from you. It seem to match just perfect.
My Addition .{1}[a-zA-Z]{1,}-?[a-zA-Z]+ simply describes what happens next.
[a-zA-Z]{1,} makes sure that there is at least one charackter after the dot, so no "-" can be written as beginning.
-?just describes that there may be appear a "-" somewhere after the first characters has been written.
[a-zA-Z]+ just says that there may come as many characters as the user want's. But not a "-" anymore.

Related

Regex pattern for search first letters of the first and last name

I have a problem with regex pattern. Every day I get names and surnames. Example:
Darkholme Van Tadashi
Herrington Billy Aniki
Johny
Walker Sam Cooler
etc..
The fact is that they are specific and do not consist of just one last name and first name.
From this list, I need to select one person (whose last name and first name I know). To do this, I found pattern:
"Darkholme|\b[vt]"
As I said, I know the person's data in advance (before the list arrives). But I only know his last name. The second and third names (Van Tadashi) are unknown to me, I only know the first letters of these names ("V" and "T"). I ran into this problem: when regex analyzes incoming data (I use regex.ismatch), it returns true if the input string is "Van Dungeonmaster". How do I create a pattern that will only return true if the surname=Darkholme, first letters of the second and third names match (=V and T)?
Perhaps I'm not making myself clear.. But in the end, it should turn out that I passed only the last name and the first letters of the first name and patronymic to pattern, and regex gave a match for input string.
If there is a comma present and the names can start with either V or T where the third name can be optional, you could use an optional group matching any non whitespace char except a comma.
\bDarkholme\s+[VT][^\s,]+(?:\s+[VT][^\s,]+)?
\b Word bounary, to prevent Darkholme being part of a larger word
Darkholme Match literally
\s+[VT] Match 1+ whitespace chars followed by either V or T
[^\s,]+ Match 1+ times any char except a whitespace char or comma
(?: Non capture group
\s+[VT] Match 1+ whitespace chars followed by either V or T
[^\s,]+ Match 1+ times any char except a whitespace char or comma
)? Close the group to make the 3rd part optional
.NET regex demo
If you know that the name starts with V for the second and T for the third:
\bDarkholme\s+V[^\s,]+(?:\s+T[^\s,]+)?
.NET regex demo
If the name can also be a Single V or T, the quantifier could be an asterix for [^\s,]*
Your pattern as is means "match any string that contains Darkholme or any string where any word starts with a v or a t" which isn't quite what you want
Perhaps
Darkholme\s+V\S*\s+T
Would suit you better. It means "darkholme followed by at least one white space then V, followed by any number of non whitespace characters then any number of whitespace followed by T

Regex which matches URN by rfc8141

I am struggling to find a Regex which could match a URN as described in rfc8141.
I have tried this one:
\A(?i:urn:(?!urn:)(?<nid>[a-z0-9][a-z0-9-]{1,31}):(?<nss>(?:[a-z0-9()+,-.:=#;$_!*']|%[0-9a-f]{2})+))\z
but this one only matches the first part of the URN without the components.
For example lets say we have the corresponding URN: urn:example:a123,0%7C00~&z456/789?+abc?=xyz#12/3 We should match the following groups:
NID - example
NSS - a123,0%7C00~&z456/789 (from the last ':' tll we match '?+' or '?=' or '#'
r-component - abc (from '?+' till '?=' or '#'')
f-component - 12/3 (from '#' till end)
I haven't read all the specifications, so there may be other rules to implement, but it should put you on the way for the optional components:
\A(?i:urn:(?!urn:)(?<nid>[a-z0-9][a-z0-9-]{1,31}):(?<nss>(?:[-a-z0-9()+,.:=#;$_!*'&~\/]|%[0-9a-f]{2})+)(?:\?\+(?<rcomponent>.*?))?(?:\?=(?<qcomponent>.*?))?(?:#(?<fcomponent>.*?))?)\z
explanations:
(?<nss>(?:[-a-z0-9()+,.:=#;$_!*'&~\/]|%[0-9a-f]{2})+) : The - has been moved to the beginning of the list to be considered in the allowed chars, or else it means "range from , to .". The characters &, ~ and / (has to be escaped with "\") have also been added to the list, or else it won't match your example.
optional components: (?:\?\+(?<rcomponent>.*?))? : inside an optional non-capturing group (?:)? to prevent capturing the identifier (the ?+, ?= and # part). The chars ? and + have to be escaped with "\". Will capture anything (.) but in lazy mode (*?) or else the first component found would capture everything until the end of the string.
See working example in Regex101
Hope that helps
If you want to validate string with Uniform Resource Names (URNs) 8141: rfc8141 You can refer to URN8141Test.java and URN8141.java
It has been used in our team for a few years.

Regex validation in ASP.Net MVC

In my demo MVC Application I have the following validation rules for validating my domain model classes.
RuleFor(m => m.Password)
.Matches(#"^(?=(\d){2,})(?=([a-z])+)(?=(\.\$\~\&)*)").WithMessage("Password should contain at least 2 digits");
But the password validation fails .
Basically I want to validate that a password input value should at least contain 2 digits, at least either one of the special characters (.$~&) and at least one alphabet in any order.
They can appear in any order.
Basically I should match the strings like
'a2ss1~A33',
'678.&aA88'
but not
'aaa2sfhdjkf^',
'aass'.
Also I just came across lookahead s in regex.
I still have a doubt why cant just we have the rule for validating the password field ?
.Matches(#"^((\d){2,})(.*[a-zA-Z])([\.\$\~\&]*)").WithMessage("Password should contain at least 2 digits");
When to use lookaheads in regex and when not to ?
You can use
^(?=(\D*\d){2})(?=[^A-Za-z]*[A-Za-z])(?=[^.$~&]*[.$~&]).*
See the regex demo.
The regex matches:
^ - start of string
(?=(\D*\d){2}) - 2 digits anywhere in the string are required
(?=[^A-Za-z]*[A-Za-z]) - an ASCII letter is required somewhere in a string
(?=[^.$~&]*[.$~&]) - the symbol from the [.$~&] set is required
.* - (optional, remove if full string match is not required) matches all characters other than a newline up to the end of the line
Lookaheads enable several checks from the same position in string (here, at the very beginning as they are all placed right after ^). The regex ^((\d){2,})(.*[a-zA-Z])([\.\$\~\&]*) requires 2 or more digits at the beginning, followed with any 0+ characters other than a newline followed with 1 letter followed with 0+ some special symbols. There can be anything else after that, since you are not checking the end of the string.

C# Regular Expression: Search the first 3 letters of each name

Does anyone know how to say I can get a regex (C#) search of the first 3 letters of a full name?
Without the use of (.*)
I used (.**)but it scrolls the text far beyond the requested name, or
if it finds the first condition and after 100 words find the second condition he return a text that is not the look, so I have to limit in number of words.
Example: \s*(?:\s+\S+){0,2}\s*
I would like to ignore names with less than 3 characters if they exist in name.
Search any name that contains the first 3 characters that start with:
'Mar Jac Rey' (regex that performs search)
Should match:
Marck Jacobs L. S. Reynolds
Marcus Jacobine Reys
Maroon Jacqueline by Reyils
Can anyone help me?
The zero or more quantifier (*) is 'greedy' by default—that is, it will consume as many characters as possible in order to finding the remainder of the pattern. This is why Mar.*Jac will match the first Mar in the input and the last Jac and everything in between.
One potential solution is just to make your pattern 'non-greedy' (*?). This will make it consume as few characters as possible in order to match the remainder of the pattern.
Mar.*?Jac.*?Rey
However, this is not a great solution because it would still match the various name parts regardless of what other text appears in between—e.g. Marcus Jacobine Should Not Match Reys would be a valid match.
To allow only whitespace or at most 2 consecutive non-whitespace characters to appear between each name part, you'd have to get more fancy:
\bMar\w*(\s+\S{0,2})*\s+Jac\w*(\s+\S{0,2})*\s+Rey\w*
The pattern (\s+\S{0,2})*\s+ will match any number of non-whitespace characters containing at most two characters, each surrounded by whitespace. The \w* after each name part ensures that the entire name is included in that part of the match (you might want to use \S* instead here, but that's not entirely clear from your question). And I threw in a word boundary (\b) at the beginning to ensure that the match does not start in the middle of a 'word' (e.g. OMar would not match).
I think what you want is this regular expression to check if it is true and is case insensitive
#"^[Mar|Jac|Rey]{3}"
Less specific:
#"^[\w]{3}"
If you want to capture the first three letters of every words of at least three characters words you could use something like :
((?<name>[\w]{3})\w+)+
And enable ExplicitCapture when initializing your Regex.
It will return you a serie of Match named "name", each one of them is a result.
Code sample :
Regex regex = new Regex(#"((?<name>[\w]{3})\w+)+", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);
var match = regex.Matches("Marck Jacobs L. S. Reynolds");
If you want capture also 3 characters words, you can replace the last "\w" by a space. In this case think to handle the last word of the phrase.

C# Regex match on special characters

I know this stuff has been talked about a lot, but I'm having a problem trying to match the following...
Example input: "test test 310-315"
I need a regex expression that recognizes a number followed by a dash, and returns 310. How do I include the dash in the regex expression though. So the final match result would be: "310".
Thanks a lot - kcross
EDIT: Also, how would I do the same thing but with the dash preceding, but also take into account that the number following the dash could be a negative number... didnt think of this one when I wrote the question immediately. for example: "test test 310--315" returns -315 and "test 310-315" returns 315.
Regex regex = new Regex(#"\d+(?=\-)");
\d+ - Looks for one or more digits
(?=\-) - Makes sure it is followed by a dash
The # just eliminates the need to escape the backslashes to keep the compiler happy.
Also, you may want this instead:
\d+(?=\-\d+)
This will check for a one or more numbers, followed by a dash, followed by one or more numbers, but only match the first set.
In response to your comment, here's a regex that will check for a number following a -, while accounting for potential negative (-) numbers:
Regex regex = new Regex(#"(?<=\-)\-?\d+");
(?<=\-) - Negative lookbehind which will check and make sure there is a preceding -
\-? - Checks for either zero or one dashes
\d+ - One or more digits
(?'number'\d+)- will work ( no need to escape ). In this example the group containing the single number is the named group 'number'.
if you want to match both groups with optional sign try:
#"(?'first'-?\d+)-(?'second'-?\d+)"
See it working here.
Just to describe, nothing complicated, just using -? to match an optional - and \d+ to match one or more digit. a literal - match itself.
here's some documentation that I use:
http://www.mikesdotnetting.com/Article/46/CSharp-Regular-Expressions-Cheat-Sheet
in the comments section of that page, it suggests escaping the dash with '\-'
make sure you escape your escape character \
You would escape the special meaning of - in regex language (means range) using a backslash (\). Since backslash has a special meaning in C# literals to escape quotes or be part of some characters, you need to escape that with another backslash(\). So essentially it would be \d+\\-.
\b\d*(?=\-) you will want to look ahead for the dash
\b = is start at a word boundry
\d = match any decimal digit
* = match the previous as many times as needed
(?=\-) = look ahead for the dash
Edited for Formatting issue with the slash not showing after posting

Categories