Regex in c# for allowing numbers and alphabets - c#

I am trying to write a regex that allows different set of inputs.
first 9 characters should be numeric - 123456789
10 character is optional and if present should be Alphabet - 123456789A
11 Character if preset should be aplphanumeric - 123456789AA or 123456789A1
12 - 14 Character if preset should be numeric - 123456789AA123 or 123456789A1123
I tried this but it is not working..
string sMatch = "^[0-9]{9}([a-zA-Z])\?{1}([0-9A-Za-z])\?{1}([0-9])?{1}([0-9])\?{1}$";
System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(sMatch);

i dont know c#'s regex implementation but how about:
\d{9}[a-zA-Z]?[a-zA-Z0-9]?\d{0,3}

Try the following
string sMatch = "^(?i)\\b\\d{9}[a-z]?[^\W_]?\\d{0,3}\\b$";
See live demo

A. You need to put an '#' character before the first quotation mark in the string to mark it as a string literal so it handles \? properly.
B. I'd break it up into a few statements, IE:
string preset1 = #"^[0-9]{9}", preset2 = #"[a-zA-Z]{1}", preset3 = #"[0-9A-Za-z]{1}",
preset4 = #"[0-9]{3}$";
if (Regex.IsMatch(input, preset1){
//Do fits first preset
if (Regex.IsMatch(input, preset1 + preset2){
//Do fits second preset
if (Regex.IsMatch(input, preset1 + preset2 + preset3)){
//Do fits third preset
if (Regex.IsMatch(input, preset1 + preset2 + preset 3 + preset4)){
//Do fits fourth preset
}
}
}
}

Related

Search for 2 specific letters followed by 4 numbers Regex

I need to check if a string begins with 2 specific letters and then is followed by any 4 numbers.
the 2 letters are "BR" so BR1234 would be valid so would BR7412 for example.
what bit of code do I need to check that the string is a match with the Regex in C#?
the regex I have written is below, there is probably a more efficient way of writing this (I'm new to RegEx)
[B][R][0-9][0-9][0-9][0-9]
You can use this:
Regex regex = new Regex(#"^BR\d{4}");
^ defines the start of the string (so there should be no other characters before BR)
BR matches - well - BR
\d is a digit (0-9)
{4} says there must be exactly 4 of the previously mentioned group (\d)
You did not specify what is allowed to follow the four digits. If this should be the end of the string, add a $.
Usage in C#:
string matching = "BR1234";
string notMatching = "someOther";
Regex regex = new Regex(#"^BR\d{4}");
bool doesMatch = regex.IsMatch(matching); // true
doesMatch = regex.IsMatch(notMatching); // false;
BR\d{4}
Some text to make answer at least 30 characters long :)

Replace a part of string containing Password

Slightly similar to this question, I want to replace argv contents:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
to this:
"-help=none\n-URL=(default)\n-password=********\n-uname=Khanna\n-p=100"
I have tried very basic string find and search operations (using IndexOf, SubString etc.). I am looking for more elegant solution so as to replace this part of string:
-password=AnyPassword
to:
-password=*******
And keep other part of string intact. I am looking if String.Replace or Regex replace may help.
What I've tried (not much of error-checks):
var pwd_index = argv.IndexOf("--password=");
string converted;
if (pwd_index >= 0)
{
var leftPart = argv.Substring(0, pwd_index);
var pwdStr = argv.Substring(pwd_index);
var rightPart = pwdStr.Substring(pwdStr.IndexOf("\n") + 1);
converted = leftPart + "--password=********\n" + rightPart;
}
else
converted = argv;
Console.WriteLine(converted);
Solution
Similar to Rubens Farias' solution but a little bit more elegant:
string argv = "-help=none\n-URL=(default)\n-password=\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)[^\n]*", "$1********");
It matches password= literally, stores it in capture group $1 and the keeps matching until a \n is reached.
This yields a constant number of *'s, though. But telling how much characters a password has, might already convey too much information to hackers, anyway.
Working example: https://dotnetfiddle.net/xOFCyG
Regular expression breakdown
( // Store the following match in capture group $1.
password= // Match "password=" literally.
)
[ // Match one from a set of characters.
^ // Negate a set of characters (i.e., match anything not
// contained in the following set).
\n // The character set: consists only of the new line character.
]
* // Match the previously matched character 0 to n times.
This code replaces the password value by several "*" characters:
string argv = "-help=none\n-URL=(default)\n-password=look\n-uname=Khanna\n-p=100";
string result = Regex.Replace(argv, #"(password=)([\s\S]*?\n)",
match => match.Groups[1].Value + new String('*', match.Groups[2].Value.Length - 1) + "\n");
You can also remove the new String() part and replace it by a string constant

Replace special characters or special characters followed by space

I have this particular string:
Administrationsomkostninger I -2.889 - r0.l l0
I would like to replace these characters:r,l and i with 1.
I use this expression:
([(t|r|l|i|)])
That gives me this string:
Adm1n1s11a11onsomkos1n1nge1 1 -2.889 - 10.1 10
Now i want to replace the all digits that contains a digit followed + a whitespace
so in this case only - 10.1 10 gets converted to -10.110
Try this
string input = "Administrationsomkostninger I -2.889 - r0.l l0";
string pattern = #"(?'spaces'\s){2,}";
string output = Regex.Replace(input, pattern, " ");
​

Can't make regex pattern for 8 and 13 digits in middle of string work

EDIT 2:
Yes like I thought, i need to change the pattern to 2 different ones, because the OR will make a match for 13 digits a match for 8 digits one
THE SOLUTION IS:
Regex EAN8 = new Regex(#"\b\d{8}\b");
Regex EAN13 = new Regex(#"\d{13}\b");
PS FOR EDIT2: As someone said, problaly in the future i will end up finding EAN1234567890123 or EAN_1234567890123, these patterns wont work out, and I have no idea where to start searching for a pattern like this.
I'm doing a project where I need to take multiple EANs from a text.
I already have a validation class to see if they are valid or not.
And I can take the 13 digits one (but I think the pattern I'm using is not correct and will give problems sooner or later.
Example of a string: "OL‐120 112 82 Estuchado, fácil apertura. 8410032002279 227 24"
as you can see there is a valid EAN13 in the middle: "8410032002279"
I'm using this pattern:
Regex EAN13 = new Regex(#"\d{13}");
It gives me the EAN inside the string, but I think the correct pattern should be like this:
Regex EAN13 = new Regex(#"\d{13}$");
But when I use it it doesn't work. probably because the string doesn't end there.
I have a similar problem with the EAN of 8 digits, if i use this pattern:
Regex EAN8 = new Regex(#"\d{8}");
It gives me the 13 digit eans cut to 8...
What should I do to make both patterns work whatever the position of the EAN is in the string and for the 8 digit return only a real string with 8 digits and not one with more cut down to 8.
Thanks in advance
EDIT: Further Code to understand what I'm doing
Regex EAN = new Regex(#"\b(?:\d{8}|\d{13})\b");
using (StreamReader sr = new StreamReader(#"....txt"))
{
string currentLine;
while ((currentLine = sr.ReadLine()) != null)
{
Match m13 = EAN.Match(currentLine);
Match m8 = EAN.Match(currentLine);
if (m8.Success)
{
lista_EAN8.Add(m8.Value);
//string valido8 = new Ean8Validate().ValidateEan8(m8.Value);
//if (valido8 == m8.Value)
//{
// lista_EAN8.Add(m8.Value);
//}
}
if (m13.Success)
{
string valido13 = new Ean13Validate().ValidateEan13(m13.Value);
if (valido13 == m13.Value)
{
lista_EAN13.Add(m13.Value);
}
}
}
}
Like this it returns me the same values in list of 13 digit eans and list of 8 digits eans
ok looks like you want 2 different Regexs one for targeting only 8 digit matches and the other for targeting 13 digit matches
for matching of the 8 digit EANs use;
\b(?:\d{8})\b
for matching and for 13 digit EANs use;
\b(?:\d{13})\b
additionally is you want an options prefix of EAN(upper or lowercase) you can use;
for 8 digit
\b(?:[Ee][Aa][Nn])?(?:\d{8})\b
for 13 digit
\b(?:[Ee][Aa][Nn])?(?:\d{8})\b
for your example you want to modify the code so it read something like this.
Regex EAN8 = new Regex(#"\b(?:\d{8})\b");
Regex EAN13 = new Regex(#"\b(?:\d{13})\b");
using (StreamReader sr = new StreamReader(#"....txt"))
{
string currentLine;
while ((currentLine = sr.ReadLine()) != null)
{
Match m13 = EAN13.Match(currentLine);
Match m8 = EAN8.Match(currentLine);
if (m8.Success)
{
lista_EAN8.Add(m8.Value);
}
if (m13.Success)
{
lista_EAN13.Add(m13.Value);
}
}
}
now if we tweek the Regexs a little more we can extract just the number parts out of EAN numbers even when they are prefixed with EAN* or EAN_*
Regex EAN8 = new Regex(#"\b(?:[Ee][Aa][Nn]_?)?(\d{8})\b");
Regex EAN13 = new Regex(#"\b(?:[Ee][Aa][Nn]_?)?(\d{13})\b");
using (StreamReader sr = new StreamReader(#"....txt"))
{
string currentLine;
while ((currentLine = sr.ReadLine()) != null)
{
Match m13 = EAN13.Match(currentLine);
Match m8 = EAN8.Match(currentLine);
if (m8.Success)
{
lista_EAN8.Add(m8.Groups[1].Value);
}
if (m13.Success)
{
lista_EAN13.Add(m13.Groups[1].Value);
}
}
}
this will capture the number part while throwing away the EAN prefix
Use the below regex to match 8 or 13 digits. \b is a word boundary which matches between a word character and a non-word character. So it avoids matching 8 digit number in a 13 digit number.
\b(?:\d{8}|\d{13})\b
Try this regex string. \b = word boundary and the | makes sure that it will only match 8 or 13 and not some number in between:
\b\d{8}\b|\b\d{13}\b
If you want dob't allow unicode digit use character class instead shortcut \d ( it's much faster)
\b(?:[0-9]{8}|[0-9]{13})\b
I managed to concoct this:
\b(([Ee][Aa][Nn])?[_]?([0-9]{13}|[0-9]{8}))\b
This part ([Ee][Aa][Nn])? groups the case-insensitive sequence EAN and makes it optional with ?
Then [_]? makes the underscore optional. I added the square brackets for prettiness sake
The digits are identified using their character representation [0-9]{13} and [0-9]{8}
Everything is wrapped up in a \b( ... )\b block to identify the word boundary
The two EAN types are wrapped by parentheses and separated by an OR |
Below is a screenshot from http://regexpal.com/ showing the testing set and the matching.
Jorge, I must say I don't like repeating code, (or anything else for that matter :D ). I am therefore not very fond of the whole ([Ee][Aa][Nn])?[_]? appearing twice. Moreover if tomorrow you wish to look for EAN5 for example you must further copy it and the regexp becomes ever more ugly.
Here is what I had before the cleanup:
\b(([Ee][Aa][Nn])?[_]?[0-9]{13}|([Ee][Aa][Nn])?[_]?[0-9]{8})\b
Below is a screenshot from http://regexpal.com/ showing the testing set and the matching.

Replace using Regular Expression - fixed digit location

I would like to replace from a number of 16 digits, it's 5th to 10th digit.
How can that be achieved with a regular expression (C#)?
The way to do it is to capture in the inner and outer portions separately, like this:
// Split into 2 groups of 5 digits and 1 of 6
string regex = "(\\d{5})(\\d{5})(\\d{6})";
// Insert ABCDEF in the middle of
// match 1 and match 3
string replaceRegex = "${1}ABCDE${3}";
string testString = "1234567890999999";
string result = Regex.Replace(testString, regex, replaceRegex);
// result = '12345ABCDE999999'
Why use a regular expression? If by "number of 16 digits", you mean a 16 character long string representation of a number, then you'd probably be better off just using substring.
string input = "0000567890000000";
var output = input.Substring(0, 4) + "222222" + input.Substring(10, 6);
Or did you mean you want to swap the 5th and 10th digits? Your question isn't very clear.
Use the regular expression (?<=^\d{4})\d{6}(?=\d{6}$) to achieve it without capture groups.
It looks for 6 consecutive digits (5th to 10th inclusively) that are preceded by the first 4 digits and the last 6 digits of the string.
Regex.Replace("1234567890123456", #"(?<=^\d{4})\d{6}(?=\d{6}$)", "replacement");
Got it...
by creating 3 capturing groups:
([\d]{5})([\d]{5})([\d]{6})
keep capturing group1 and 3 and replace group2 with stars (or whatever)
$1*****$3
C# code below
string resultString = null;
try {
resultString = Regex.Replace(subjectString, #"([\d]{5})([\d]{5})([\d]{6})", "$1*****$2", RegexOptions.Singleline);
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}

Categories