Mask the Phone no using Regex in c# - c#

We have a Phone no field, which can be of maximum 9 digit and we need to mask the Phone no (which is basically a string) to show on UI as a mask value.
We have tried below code snippet :
var pattern="^(/d{2})(/d{3})(/d*)$";
var regExp=new Regex(pattern);
return regExp.Replace(value, "$1-$2-$3");
this snippet works for 123456789 and displays (123) 456-789, but for 12345 it displays () 12-345.
Could you please suggest what will be the best suitable option here to display phone no as (123) 456-789 for 123456789 and (123) 45 for 12345 Phone no.

Try following :
string[] inputs = { "123456789", "12345" };
string pattern = #"^(?'one'\d{3})(?'two'\d{3})(?'three'\d{3})|(?'one'\d{3})(?'two'\d{2})";
string output = "";
foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern);
if (match.Groups["three"].Value == "")
output = string.Format("({0}) {1}", match.Groups["one"].Value, match.Groups["two"].Value);
else
output = string.Format("({0}) {1}-{2}", match.Groups["one"].Value, match.Groups["two"].Value, match.Groups["three"].Value);
}

Related

How do I Split the string into two separate variables in C#

I have a string that I want to store in two different varaibles in C#.
s= "Name=team1; ObjectGUID=d8fd5125-b065-48cb-b5f3-c20f509b7476"
I want Var1 = team1 & Var2 = d8fd5125-b065-48cb-b5f3-c20f509b7476
Here's what I am trying to do:
var1 = s.Replace("Name=","").Replace("; ObjectGUID=", "");
But I am not able to figure out how to bifurcate the Name value to var1 and eliminate the rest. And it is possible that the value of 'Name' could vary so I can't fix the length to chop off.
You could use a regex where the value of Name could be captured in group 1 matching not a ; using a negated character class.
The value of ObjectGUID could be captured in group 2 using a repeated pattern matching 1+ times a digit 0-9 or characters a-f. Then repeat that pattern 1+ times preceded with a -
Name=([^;]+); ObjectGUID=([a-f0-9]+(?:-[a-f0-9]+)+)
.NET regex demo | C# demo
For example:
string pattern = #"Name=([^;]+); ObjectGUID=([a-f0-9]+(?:-[a-f0-9]+)+)";
string s= "Name=team1; ObjectGUID=d8fd5125-b065-48cb-b5f3-c20f509b7476";
Match m = Regex.Match(s, pattern);
string var1 = m.Groups[1].Value;
string var2 = m.Groups[2].Value;
Console.WriteLine(var1);
Console.WriteLine(var2);
Result
team1
d8fd5125-b065-48cb-b5f3-c20f509b7476
Split by ';' then split by '='. Also works for any key/value pairs such as the ones in connection strings.
var values = s.Split(';').Select(kv => kv.Split('=')[1]).ToArray();
var var1 = values[0];
var val2 = values[1];
You can use IndexOf to take point at "=" and Substring to take the next value.
using System;
public class SubStringTest {
public static void Main() {
string [] info = { "Name: Felica Walker", "Title: Mz.",
"Age: 47", "Location: Paris", "Gender: F"};
int found = 0;
Console.WriteLine("The initial values in the array are:");
foreach (string s in info)
Console.WriteLine(s);
Console.WriteLine("\nWe want to retrieve only the key information. That
is:");
foreach (string s in info) {
found = s.IndexOf(": ");
Console.WriteLine(" {0}", s.Substring(found + 2));
}
}
}
The example displays the following output:
The initial values in the array are:
Name: Felica Walker
Title: Mz.
Age: 47
Location: Paris
Gender: F
We want to retrieve only the key information. That is:
Felica Walker
Mz.
47
Paris
F

regex to exact match 11 digit phone number from string and remove hyphen(-) from match in c#

I am creating a text parser in c# windows form and I want to identify 11 digit phone numbers starting from 0 with a - separator, eg 0341-2239548 or 021-34223311 should be converted to 03412239548 and 02134223311 respectively using Regex.Match. I am unable to find the relevant regex expression, can anyone help me please?
string[] RemoveCharacter = { "\"", "(", ")", "/=", "/", ":-", ":", ";", "-" };
foreach (string word in RemoveCharacter)
{
s = s.Replace(word, " ");
}
after removing these characters, phone numbers are also separated by a space and I do not want that to happen only for phone numbers.
You can use below Regex to remove all hyphens and all other non numeric characters from phone number
string pattern = #"\b([\-]?\d[\-]?){11}\b";
Regex rgx = new Regex(pattern);
var sentence = "This is phone number 0341-2239548 and 021-34223311";
var matches = rgx.Matches(sentence);
foreach (Match match in matches)
{
string replacedValue = Regex.Replace(match.Value, #"[^0-9]", "");
sentence = sentence.Replace(match.Value, replacedValue);
}
See the demo
if you have a string like that, just remove your seperator. You dont need a regex for that:
string nr = "0154-1452146";
nr = nr.Replace("-", "");
Console.WriteLine(nr);

C# regular expression

I have string like this:
{F971h}[0]<0>some result code: 1
and I want to split it into:
F971
0
0
some result code: 1
I know I can first split "{|}|[|]|<|>" it into:
{F971h}
[0]
<0>
some result code: 1
and next: {F971h} -> F971; [0] -> 0; etc.
But how can I do it with one regular expression?
I try somethink like this:
Regex rgx = new Regex(#"(?<timestamp>[0-9A-F]+)" + #"(?<subsystem>\d+)" + #"(?<level>\d+)" + #"(?<messagep>[0-9A-Za-z]+)");
var result = rgx.Matches(input);
You can try just Split without any regular expressions:
string source = "{F971h}[0]<0>some result code: 1";
string[] items = source.Split(new char[] { '{', '}', '[', ']', '<', '>' },
StringSplitOptions.RemoveEmptyEntries);
Test:
// F971h
// 0
// 0
// some result code: 1
Console.Write(String.Join(Environment.NewLine, items));
There are two issues with your regex:
You do not allow lowercase ASCII letters in the first capture group (add a-z or a RegexOptions.IgnoreCase flag)
The delimiting characters are missing in the pattern (<, >, [, ], etc.)
Use
{(?<timestamp>[0-9a-zA-F]+)}\[(?<subsystem>\d+)]<(?<level>\d+)>(?<messagep>.+)
^ ^^^ ^^^ ^^ ^
See the regex demo
Since the messagep group should match just the rest of the line, I suggest just using .+ at the end. Else, you'd need to replace your [0-9A-Za-z]+ that does not allow whitespace with something like [\w\s]+ (match all word chars and whitespaces, 1 or more times).
C# code:
var s = #"{F971h}[0]<0>some result code: 1";
var pat = #"{(?<timestamp>[0-9a-zA-F]+)}\[(?<subsystem>\d+)]<(?<level>\d+)>(?<messagep>.+)";
var m = Regex.Match(s, pat);
if (m.Success)
{
Console.Out.WriteLine(m.Groups["timestamp"].Value);
Console.Out.WriteLine(m.Groups["subsystem"].Value);
Console.Out.WriteLine(m.Groups["level"].Value);
Console.Out.WriteLine(m.Groups["messagep"].Value);
}
Or for a multiline string containing multiple matches:
var s = "{F971h}[0]<0>some result code: 1\r\n{FA71h}[0]<0>some result code: 3\r\n{FB72h}[0]<0>some result code: 5";
var pat = #"{(?<timestamp>[0-9a-zA-F]+)}\[(?<subsystem>\d+)]<(?<level>\d+)>(?<messagep>[^\r\n]+)";
var res = System.Text.RegularExpressions.Regex.Matches(s, pat)
.Cast<System.Text.RegularExpressions.Match>()
.Select(x => new[] {
x.Groups["timestamp"].Value,
x.Groups["subsystem"].Value,
x.Groups["level"].Value,
x.Groups["messagep"].Value})
.ToList();
You can get it like that:
string line = #"{F971h}[0]<0>some result code: 1";
var matchCollection = Regex.Matches(line, #"\{(?<timestamp>.*?)\}\[(?<subsystem>.*?)\]<(?<level>.*?)>(?<messagep>.*)");
if (matchCollection.Count > 0)
{
string timestamp = matchCollection[0].Groups["timestamp"].Value;
string subsystem = matchCollection[0].Groups["subsystem"].Value;
string level = matchCollection[0].Groups["level"].Value;
string messagep = matchCollection[0].Groups["messagep"].Value;
Console.Out.WriteLine("First part is {0}, second: {1}, thrid: {2}, last: {3}", timestamp, subsystem, level, messagep);
}
else
{
Console.Out.WriteLine("No match found.");
}
You can watch it live here on regex storm. You'll have to learn about:
Named capture groups
Repetitions
Thank you all! Code below works for me. I missed that it can be multiple string:
{F971h}[0]<0>some result code: 1\r\n{FA71h}[0]<0>some result code: 3\r\n{FB72h}[0]<0>some result code: 5
code:
var pat = #"{(?<timestamp>[0-9a-zA-F]+)}\[(?<subsystem>\d+)]<(?<level>\d+)>(?<message>.+)";
var collection = Regex.Matches(input, pat);
foreach (Match m in collection)
{
var timestamp = m.Groups["timestamp"];
var subsystem = m.Groups["subsystem"];
var level = m.Groups["level"];
var message = m.Groups["message"];
}

Locate RegEx match then extract

I am trying to read text from a RichTextBox in order to locate the first occurrence of a matched expression. I would then like to extract the string that satisfies they query so I can use it as a variable. Below is the basic bit of code I have to start of with and build upon.
private string returnPostcode()
{
string[] allLines = rtxtDocViewer.Text.Split('\n');
string expression = string expression = "^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$"
foreach (string line in allLines)
{
if (Regex.Matches(line, expression, RegexOptions.Count > 0)
{
//extract and return the string that is found
}
}
}
Example of what's contained in the RichTextBox is below. I want to extract "E12 8SD" which the above regex should be able to find. Thanks
Damon Brown
Flat B University Place
26 Park Square
London
E12 8SD
Mobile: 1111 22222
Email: dabrown192882#gmail.com Date of birth: 21/03/1986
Gender: Male
Marital Status: Single
Nationality: English
Summary
I have acquired a multifaceted skill set with experience using several computing platforms.
You need to use Regex.IsMatch and remove the RegexOptions.Count > 0
string[] allLines = s.Split('\n');
string expression = "^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([AZa-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$";
foreach (string line in allLines)
{
if (Regex.IsMatch(line, expression)) // Regex.IsMatch will check if a string matches the regex
{
Console.WriteLine(line); // Print the matched line
}
}
See the IDEONE Demo
Quite possible that your text contains CR+LF line breaks. Then, adjust your code as follows:
string[] allLines = s.Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries);
See this demo
UPDATE
To just extract the code with your regex, you need not split the contents into lines, just use a Regex.Match on the whole text:
string s = "Damon Brown\nFlat B University Place\n26 Park Square \nLondon\nTW1 1AJ Twickenham Mobile: +44 (0) 7711223344\nMobile: 1111 22222\nEmail: dabrown192882#gmail.com Date of birth: 21/03/1986\nGender: Male\nMarital Status: Single\nNationality: English\nSummary\nI have acquired a multifaceted skill set with experience using several computing platforms.";
string expression = #"(?i)\b(gir 0a{2})|((([a-z][0-9]{1,2})|(([a-z][a-hj-y][0-9]{1,2})|(([a-z][0-9][a-z])|([a-z][a-hj-y][0-9]?[a-z])))) [0-9][a-z]{2})\b";
Match res = Regex.Match(s, expression);
if (res.Success)
Console.WriteLine(res.Value); // = > TW1 1AJ
I also removed the uppercase ranges to replace them with a case-insensitive modifier (?i).
See this IDEONE demo.

what regex must i use to split this?

i am very newbie to c#..
i want program if input like this
input : There are 4 numbers in this string 40, 30, and 10
output :
there = string
are = string
4 = number
numbers = string
in = string
this = string
40 = number
, = symbol
30 = number
, = symbol
and = string
10 = number
i am try this
{
class Program
{
static void Main(string[] args)
{
string input = "There are 4 numbers in this string 40, 30, and 10.";
// Split on one or more non-digit characters.
string[] numbers = Regex.Split(input, #"(\D+)(\s+)");
foreach (string value in numbers)
{
Console.WriteLine(value);
}
}
}
}
but the output is different from what i want.. please help me.. i am stuck :((
The regex parser has an if conditional and the ability to group items into named capture groups; to which I will demonstrate.
Here is an example where the patttern looks for symbols first (only a comma add more symbols to the set [,]) then numbers and drops the rest into words.
string text = #"There are 4 numbers in this string 40, 30, and 10";
string pattern = #"
(?([,]) # If a comma (or other then add it) is found its a symbol
(?<Symbol>[,]) # Then match the symbol
| # else its not a symbol
(?(\d+) # If a number
(?<Number>\d+) # Then match the numbers
| # else its not a number
(?<Word>[^\s]+) # So it must be a word.
)
)
";
// Ignore pattern white space allows us to comment the pattern only, does not affect
// the processing of the text!
Regex.Matches(text, pattern, RegexOptions.IgnorePatternWhitespace)
.OfType<Match>()
.Select (mt =>
{
if (mt.Groups["Symbol"].Success)
return "Symbol found: " + mt.Groups["Symbol"].Value;
if (mt.Groups["Number"].Success)
return "Number found: " + mt.Groups["Number"].Value;
return "Word found: " + mt.Groups["Word"].Value;
}
)
.ToList() // To show the result only remove
.ForEach(rs => Console.WriteLine (rs));
/* Result
Word found: There
Word found: are
Number found: 4
Word found: numbers
Word found: in
Word found: this
Word found: string
Number found: 40
Symbol found: ,
Number found: 30
Symbol found: ,
Word found: and
Number found: 10
*/
Once the regex has tokenized the resulting matches, then we us linq to extract out those tokens by identifying which named capture group has a success. In this example we get the successful capture group and project it into a string to print out for viewing.
I discuss the regex if conditional on my blog Regular Expressions and the If Conditional for more information.
You could split using this pattern: #"(,)\s?|\s"
This splits on a comma, but preserves it since it is within a group. The \s? serves to match an optional space but excludes it from the result. Without it, the split would include the space that occurred after a comma. Next, there's an alternation to split on whitespace in general.
To categorize the values, we can take the first character of the string and check for the type using the static Char methods.
string input = "There are 4 numbers in this string 40, 30, and 10";
var query = Regex.Split(input, #"(,)\s?|\s")
.Select(s => new
{
Value = s,
Type = Char.IsLetter(s[0]) ?
"String" : Char.IsDigit(s[0]) ?
"Number" : "Symbol"
});
foreach (var item in query)
{
Console.WriteLine("{0} : {1}", item.Value, item.Type);
}
To use the Regex.Matches method instead, this pattern can be used: #"\w+|,"
var query = Regex.Matches(input, #"\w+|,").Cast<Match>()
.Select(m => new
{
Value = m.Value,
Type = Char.IsLetter(m.Value[0]) ?
"String" : Char.IsDigit(m.Value[0]) ?
"Number" : "Symbol"
});
Well to match all numbers you could do:
[\d]+
For the strings:
[a-zA-Z]+
And for some of the symbols for example
[,.?\[\]\\\/;:!\*]+
You can very easily do this like so:
string[] tokens = Regex.Split(input, " ");
foreach(string token in tokens)
{
if(token.Length > 1)
{
if(Int32.TryParse(token))
{
Console.WriteLine(token + " = number");
}
else
{
Console.WriteLine(token + " = string");
}
}
else
{
if(!Char.isLetter(token ) && !Char.isDigit(token))
{
Console.WriteLine(token + " = symbol");
}
}
}
I do not have an IDE handy to test that this compiles. Essentially waht you are doing is splitting the input on space and then performing some comparisons to determine if it is a symbol, string, or number.
If you want to get the numbers
var reg = new Regex(#"\d+");
var matches = reg.Matches(input );
var numbers = matches
.Cast<Match>()
.Select(m=>Int32.Parse(m.Groups[0].Value));
To get your output:
var regSymbols = new Regex(#"(?<number>\d+)|(?<string>\w+)|(?<symbol>(,))");
var sMatches = regSymbols.Matches(input );
var symbols = sMatches
.Cast<Match>()
.Select(m=> new
{
Number = m.Groups["number"].Value,
String = m.Groups["string"].Value,
Symbol = m.Groups["symbol"].Value
})
.Select(
m => new
{
Match = !String.IsNullOrEmpty(m.Number) ?
m.Number : !String.IsNullOrEmpty(m.String)
? m.String : m.Symbol,
MatchType = !String.IsNullOrEmpty(m.Number) ?
"Number" : !String.IsNullOrEmpty(m.String)
? "String" : "Symbol"
}
);
edit
If there are more symbols than a comma you can group them in a class, like #Bogdan Emil Mariesan did and the regex will be:
#"(?<number>\d+)|(?<string>\w+)|(?<symbol>[,.\?!])"
edit2
To get the strings with =
var outputLines = symbols.Select(m=>
String.Format("{0} = {1}", m.Match, m.MatchType));

Categories