Find phone number from given string c# - c#

I have one resume , i want to find user's contact number(Mobile no or Phone no)
from the resume, Need any idea or solution or any assistance for achieving the goal .
What i Have tried so far....
var numString = "";
string strData = ",38,,,,,,,,,,,,,,,,,,,,,,,,,,,,382350,,,,,0,,,,8141884584,,,,,,,,";
char[] separator = new char[] { ',' };
string[] strSplitArr = strData.Split(separator);
for (int q = 0; q < strSplitArr.Length; q++)
{
if (strSplitArr[q] != "")
{
int no = 0;
no = strSplitArr[q].Length;
if (no >= 10 && no <= 12)
{
numString += strSplitArr[q].ToString() + ", ";
}
}
}

I would suggest that you use Regular Expression
Here is a sample code to find US Phone numbers:
string text = MyInputMethod();
const string MatchPhonePattern =
#"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}";
Regex rx = new Regex(MatchPhonePattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
// Find matches.
MatchCollection matches = rx.Matches(text);
// Report the number of matches found.
int noOfMatches = matches.Count;
//Do something with the matches
foreach (Match match in matches)
{
//Do something with the matches
string tempPhoneNumber= match.Value.ToString(); ;
}

Related

Clean string to have only numbers c#

I want to do have only the numbers from a string. I have tried this:
string phoneNumber = txtPhoneNumber.Text;
string cleanPhoneNumber = string.Empty;
foreach (char c in phoneNumber)
{
if (c.Equals('0') || c.Equals('1') || c.Equals('2') ||
c.Equals('3') || c.Equals('4') || c.Equals('5') ||
c.Equals('6') || c.Equals('7') || c.Equals('8') ||
c.Equals('9'))
cleanPhoneNumber += Convert.ToString(c);
}
The solution above worked, but i want to know if there is a more efficient way.
string b = string.Empty;
for (int i=0; i< a.Length; i++)
{
if (Char.IsDigit(a[i]))
b += a[i];
}
Or use Regex
resultString = Regex.Match(subjectString, #"\d+").Value;
Since you, probable, want digits in 0..9 range only, not all unicode ones (which include Persian, Indian digits etc.), char.IsDigit and \d regular expression are not exact solutions.
Linq:
string cleanPhoneNumber = string.Concat(phoneNumber.Where(c => c >= '0' && c <= '9'));
Regex:
either Sami's, integer's codes or
resultString = Regex.Match(subjectString, #"\d+", RegexOptions.ECMAScript ).Value;
which is Krystian Borysewicz's solution with ECMAScript option to be on the safe side.
string phoneNumber = txtPhoneNumber.Text;
// Get numbers only
Regex numbersRegex = new Regex("[^0-9]");
var cleanPhoneNumber = numbersRegex.Replace(phoneNumber, ""));
If you're looking to be efficient in terms on time then you should avoid using regex as the Regex class will need to parse your expression before it applies it to the phone number.
The code below avoid regex and keeps memory allocations to a minimum. It only allocates twice, once for a buffer to store the numbers and the once again at the end to create the string containing the valid numbers.
string Clean(string text)
{
var validCharacters = new char[text.Length];
var next = 0;
for(int i = 0; i < text.Length; i++)
{
char c = text[i];
if(char.IsDigit(c))
{
validCharacters[next++] = c;
}
}
return new string(validCharacters, 0, next);
}
using Linq:
string cleanPhoneNumber = new String(phoneNumber.Where(Char.IsDigit).ToArray());

Repeat substrings N times

I receive series of strings followed by non-negative numbers, e.g. "a3". I have to print on the console each string repeated N times (uppercase) where N is a number in the input. In the example, the result: "AAA". As you see, I have tried to get the numbers from the input and I think it's working fine. Can you help me with the repeating?
string input = Console.ReadLine();
//input = "aSd2&5s#1"
MatchCollection matched = Regex.Matches(input, #"\d+");
List<int> repeatsCount = new List<int>();
foreach (Match match in matched)
{
int repeatCount = int.Parse(match.Value);
repeatsCount.Add(repeatCount);
}
//repeatsCount: [2, 5, 1]
//expected output: ASDASD&&&&&S# ("aSd" is converted to "ASD" and repeated twice;
// "&" is repeated 5 times; "s#" is converted to "S#" and repeated once.)
For example, if we have "aSd2&5s#1":
"aSd" is converted to "ASD" and repeated twice; "&" is repeated 5 times; "s#" is converted to "S#" and repeated once.
Let the pattern include two groups: value to repeat and how many times to repeat:
#"(?<value>[^0-9]+)(?<times>[0-9]+)"
Then we can operate with these groups, say, with a help of Linq:
string source = "aSd2&5s#1";
string result = string.Concat(Regex
.Matches(source, #"(?<value>[^0-9]+)(?<times>[0-9]+)")
.OfType<Match>()
.SelectMany(match => Enumerable // for each match
.Repeat(match.Groups["value"].Value.ToUpper(), // repeat "value"
int.Parse(match.Groups["times"].Value)))); // "times" times
Console.Write(result);
Outcome:
ASDASD&&&&&S#
Edit: Same idea without Linq:
StringBuilder sb = new StringBuilder();
foreach (Match match in Regex.Matches(source, #"(?<value>[^0-9]+)(?<times>[0-9]+)")) {
string value = match.Groups["value"].Value.ToUpper();
int times = int.Parse(match.Groups["times"].Value);
for (int i = 0; i < times; ++i)
sb.Append(value);
}
string result = sb.ToString();
You can extract substring and how often it should be repeated with this regex:
(?<content>.+?)(?<count>\d+)
Now you can use a StringBuilder to create output string. Full code:
var input = "aSd2&5s#1";
var regex = new Regex("(?<content>.+?)(?<count>\\d+)");
var matches = regex.Matches(input).Cast<Match>();
var sb = new StringBuilder();
foreach (var match in matches)
{
var count = int.Parse(match.Groups["count"].Value);
for (var i = 0; i < count; ++i)
sb.Append(match.Groups["content"].Value.ToUpper());
}
Console.WriteLine(sb.ToString());
Output is
ASDASD&&&&&S#
Another solution without LINQ
i tried to keep the solution so it would be similar to yours
string input = "aSd2&5s#1";
var matched = Regex.Matches(input, #"\d+");
var builder = new StringBuilder();
foreach (Match match in matched)
{
string stingToDuplicate = input.Split(Char.Parse(match.Value))[0];
input = input.Replace(stingToDuplicate, String.Empty).Replace(match.Value, String.Empty);
for (int i = 0; i < Convert.ToInt32(match.Value); i++)
{
builder.Append(stingToDuplicate.ToUpper());
}
}
and finally Console.WriteLine(builder.ToString());
which result ASDASD&&&&&S#
My solution is same as others with slight differences :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication107
{
class Program
{
static void Main(string[] args)
{
string input = "aSd2&5s#1";
string pattern1 = #"[a-zA-z#&]+\d+";
MatchCollection matches = Regex.Matches(input, pattern1);
string output = "";
foreach(Match match in matches.Cast<Match>().ToList())
{
string pattern2 = #"(?'string'[^\d]+)(?'number'\d+)";
Match match2 = Regex.Match(match.Value, pattern2);
int number = int.Parse(match2.Groups["number"].Value);
string str = match2.Groups["string"].Value;
output += string.Join("",Enumerable.Repeat(str.ToUpper(), number));
}
Console.WriteLine(output);
Console.ReadLine();
}
}
}
Very simple program. No linq nothing, simple string and for loop.
string input = "aSd2&5s#1";
char[] inputArray = input.ToCharArray();
string output = "";
string ab = "";
foreach (char c in inputArray)
{
int x;
string y;
if(int.TryParse(c.ToString(), out x))
{
string sb = "";
ab = ab.ToUpper();
for(int i=0;i<b;i++)
{
sb += ab;
}
ab = "";
output += sb;
}
else
{
ab += c;
}
}
if(!string.IsNullOrEmpty(ab))
{
output += ab.ToUpper();
}
Console.WriteLine(output);
Hope it helps.

How do I break a long String in c# without breaking a words

I want to break a long String in c# without breaking a words
Example: S AAA BBBBBBB CC DDDDDD V Breaking Character on 7 Count:
S AAA
BBBBBBB
CC
DDDDDD
V
How do I do this?
string inputStr = "S AAA BBBBBBB CC DDDDDD V ";
int maxWordLength = 7;
char separator = ' ';
string[] splitted = inputStr.Split(new[]{separator}, StringSplitOptions.RemoveEmptyEntries);
var joined = new Stack<string>();
joined.Push(splitted[0]);
foreach (var str in splitted.Skip(1))
{
var strFromStack = joined.Pop();
var joindedStr = strFromStack + separator + str;
if(joindedStr.Length > maxWordLength)
{
joined.Push(strFromStack);
joined.Push(str);
}
else
{
joined.Push(joindedStr);
}
}
var result = joined.Reverse().ToArray();
Console.WriteLine ("number of words: {0}", result.Length);
Console.WriteLine( string.Join(Environment.NewLine, result) );
prints:
number of words: 5
S AAA
BBBBBBB
CC
DDDDDD
V
Here's a shorter solution harnessing the power of regular expressions.
string input = "S AAA BBBBBBB CC DDDDDD V";
// Match up to 7 characters with optional trailing whitespace, but only on word boundaries
string pattern = #"\b.{1,7}\s*\b";
var matches = Regex.Matches(input, pattern);
foreach (var match in matches)
{
Debug.WriteLine(match.ToString());
}
This does the trick if I've understood your question correctly. A recursive implementation would have been cooler, but tail recursion is too damn bad in C# :)
Could also be implemented with yield and IEnumerable<string>.
string[] splitSpecial(string words, int lenght)
{
// The new result, will be turned into string[]
var newSplit = new List<string>();
// Split on normal chars, ie newline, space etc
var splitted = words.Split();
// Start out with null
string word = null;
for (int i = 0; i < splitted.Length; i++)
{
// If first word, add
if (word == null)
{
word = splitted[i];
}
// If too long, add
else if (splitted[i].Length + 1 + word.Length > lenght)
{
newSplit.Add(word);
word = splitted[i];
}
// Else, concatenate and go again
else
{
word += " " + splitted[i];
}
}
// Flush what we have left, ie the last word
newSplit.Add(word);
// Convert into string[] (a requirement?)
return newSplit.ToArray();
}
Why not to try regex?
(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)
and use all captures.
C# code:
var text = "S AAA BBBBBBB CC DDDDDD V";
var matches = new Regex(#"(?:^|\s)(?:(.{1,7}|\S{7,}))(?=\s|$)").Matches(text).Cast<Match>().Select(x => x.Groups[1].Value).ToArray();
foreach (var match in matches)
{
Console.WriteLine(match);
}
Output:
S AAA
BBBBBBB
CC
DDDDDD
V
string str = "S AAA BBBBBBB CC DDDDDD V";
var words = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
List<string> result = new List<string>();
for (int i = 0; i < words.Length; ++i)
{
if (sb.Length == 0)
{
sb.Append(words[i]);
}
else if (sb.Length + words[i].Length < 7)
{
sb.Append(' ');
sb.Append(words[i]);
}
else
{
result.Add(sb.ToString());
sb.Clear();
sb.Append(words[i]);
}
}
if (sb.Length > 0)
{
result.Add(sb.ToString());
}
Results will contain:
S AAA
BBBBBBB
CC
DDDDDD
V
The predicate can be adjusted depending on if the separator between words should be included in the 7 characters or not.
This is how to add row break to HTML text:
SplitLongText(string _SourceText, int _MaxRowLength)
{
if (_SourceText.Length < _MaxRowLength)
{
return _SourceText;
}
else
{
string _RowBreakText="";
int _CurrentPlace = 0;
while (_CurrentPlace < _SourceText.Length)
{
if (_SourceText.Length - _CurrentPlace < _MaxRowLength)
{
_RowBreakText += _SourceText.Substring(_CurrentPlace);
_CurrentPlace = _SourceText.Length;
}
else
{
string _PartString = _SourceText.Substring(_CurrentPlace, _MaxRowLength);
int _LastSpace = _PartString.LastIndexOf(" ");
if (_LastSpace > 0)
{
_RowBreakText += _PartString.Substring(0, _LastSpace) + "<br/>" + _PartString.Substring(_LastSpace, (_PartString.Length - _LastSpace));
}
else
{
_RowBreakText += _PartString + "<br/>";
}
_CurrentPlace += _MaxRowLength;
}
}
return _RowBreakText;
}
2021
Look at this extension method, it uses recursivity
public static string SubstringDontBreakWords(this string str, int maxLength)
{
return str.Length <= maxLength ? str : str.Substring(0, str.LastIndexOf(" ")).Trim().SubstringDontBreakWords(maxLength);
}
Use it like this
string text = "Hello friends";
text.SubstringDontBreakWords(10)

How can I search through a string in C# and replace areas bounded by a pattern?

We tried a few solutions now that try and use XML parsers. All fail because the strings are not always 100% valid XML. Here's our problem.
We have strings that look like this:
var a = "this is a testxxx of my data yxxx and of these xxx parts yxxx";
var b = "hello testxxx world yxxx ";
"this is a testxxx3yxxx and of these xxx1yxxx";
"hello testxxx1yxxx ";
The key here is that we want to do something to the data between xxx and yxxx. In the example above I would need a function that counts words and replaces the strings with a word count.
Is there a way we can process the string a and apply a function to change the data that's between the xxx and yxxx? Any function right now as we're just trying to get an idea of how to code this.
You can use Split method:
var parts = a.Split(new[] {"xxx", "yxxx"}, StringSplitOptions.None)
.Select((s, index) =>
{
string s1 = index%2 == 1 ? string.Format("{0}{2}{1}", "xxx", "yxxx", s + "1") : s;
return s1;
});
var result = string.Join("", parts);
If it always going to xxx and yxxx, you can use regex as suggested.
var stringBuilder = new StringBuilder();
Regex regex = new Regex("xxx(.*?)yxxx");
var splitGroups = Regex.Match(a);
foreach(var group in splitGroups)
{
var value = splitGroupsCopy[i];
// do something to value and then append it to string builder
stringBuilder.Append(string.Format("{0}{1}{2}", "xxx", value, "yxxx"));
}
I suppose this is as basic as it gets.
Using Regex.Replace will replace all the matches with your choice of text, something like this:
Regex rgx = new Regex("xxx.+yxxx");
string cleaned = rgx.Replace(a, "replacementtext");
This code will process each of the parts delimited by "xxx". It preserves the "xxx" separators. If you do not want to preserve the "xxx" separators, remove the two lines that say "result.Append(separator);".
Given:
"this is a testxxx of my data yxxx and there are many of these xxx parts yxxx"
It prints:
"this is a testxxx>> of my data y<<xxx and there are many of these xxx>> parts y<<xxx"
I'm assuming that's the kind of thing you want. Add your own processing to "processPart()".
using System;
using System.Text;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string text = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";
string separator = "xxx";
var result = new StringBuilder();
int index = 0;
while (true)
{
int start = text.IndexOf(separator, index);
if (start < 0)
{
result.Append(text.Substring(index));
break;
}
result.Append(text.Substring(index, start - index));
int end = text.IndexOf(separator, start + separator.Length);
if (end < 0)
{
throw new InvalidOperationException("Unbalanced separators.");
}
start += separator.Length;
result.Append(separator);
result.Append(processPart(text.Substring(start, end-start)));
result.Append(separator);
index = end + separator.Length;
}
Console.WriteLine(result);
}
private static string processPart(string part)
{
return ">>" + part + "<<";
}
}
}
[EDIT] Here's the code amended to work with two different separators:
using System;
using System.Text;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
string text = "this is a test<pre> of my data y</pre> and there are many of these <pre> parts y</pre>";
string separator1 = "<pre>";
string separator2 = "</pre>";
var result = new StringBuilder();
int index = 0;
while (true)
{
int start = text.IndexOf(separator1, index);
if (start < 0)
{
result.Append(text.Substring(index));
break;
}
result.Append(text.Substring(index, start - index));
int end = text.IndexOf(separator2, start + separator1.Length);
if (end < 0)
{
throw new InvalidOperationException("Unbalanced separators.");
}
start += separator1.Length;
result.Append(separator1);
result.Append(processPart(text.Substring(start, end-start)));
result.Append(separator2);
index = end + separator2.Length;
}
Console.WriteLine(result);
}
private static string processPart(string part)
{
return "|" + part + "|";
}
}
}
The indexOf() function will return to you the index of the first occurrence of a given substring.
(My indices might be a bit off, but) I would suggest doing something like this:
var searchme = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";
var startindex= searchme.indexOf("xxx");
var endindex = searchme.indexOf("yxxx") + 3; //added 3 to find the index of the last 'x' instead of the index of the 'y' character
var stringpiece = searchme.substring(startindex, endindex - startindex);
and you can repeat that while startindex != -1
Like I said, the indices might be slightly off, you might have to add a +1 or -1 somewhere, but this will get you along nicely (I think).
Here is a little sample program that counts chars instead of words. But you should just need to change the processor function.
var a = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";
a = ProcessString(a, CountChars);
string CountChars(string a)
{
return a.Length.ToString();
}
string ProcessString(string a, Func<string, string> processor)
{
int idx_start, idx_end = -4;
while ((idx_start = a.IndexOf("xxx", idx_end + 4)) >= 0)
{
idx_end = a.IndexOf("yxxx", idx_start + 3);
if (idx_end < 0)
break;
var string_in_between = a.Substring(idx_start + 3, idx_end - idx_start - 3);
var newString = processor(string_in_between);
a = a.Substring(0, idx_start + 3) + newString + a.Substring(idx_end, a.Length - idx_end);
idx_end -= string_in_between.Length - newString.Length;
}
return a;
}
I would use Regex Groups:
Here my solution to get the parts in the string:
private static IEnumerable<string> GetParts( string searchFor, string begin, string end ) {
string exp = string.Format("({0}(?<searchedPart>.+?){1})+", begin, end);
Regex regex = new Regex(exp);
MatchCollection matchCollection = regex.Matches(searchFor);
foreach (Match match in matchCollection) {
Group #group = match.Groups["searchedPart"];
yield return #group.ToString();
}
}
you can use it like to get the parts:
string a = "this is a testxxx of my data yxxx and there are many of these xxx parts yxxx";
IEnumerable<string> parts = GetParts(a, "xxx", "yxxx");
To replace the parts in the original String you can use the Regex Group to determine Length and StartPosition (#group.Index, #group.Length).

loop through string to find substring

I have this string:
text = "book//title//page/section/para";
I want to go through it to find all // and / and their index.
I tried doing this with:
if (text.Contains("//"))
{
Console.WriteLine(" // index: {0} ", text.IndexOf("//"));
}
if (text.Contains("/"))
{
Console.WriteLine("/ index: {0} :", text.IndexOf("/"));
}
I was also thinking about using:
Foreach(char c in text)
but it will not work since // is not a single char.
How can I achieve what I want?
I tried this one also but did not display result
string input = "book//title//page/section/para";
string pattern = #"\/\//";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = rgx.Matches(input);
if (matches.Count > 0)
{
Console.WriteLine("{0} ({1} matches):", input, matches.Count);
foreach (Match match in matches)
Console.WriteLine(" " + input.IndexOf(match.Value));
}
Thank you in advance.
Simple:
var text = "book//title//page/section/para";
foreach (Match m in Regex.Matches(text, "//?"))
Console.WriteLine(string.Format("Found {0} at index {1}.", m.Value, m.Index));
Output:
Found // at index 4.
Found // at index 11.
Found / at index 17.
Found / at index 25.
Would it be possible using Split?
So:
string[] words = text.Split(#'/');
And then go through the words? You would have blanks, due to the //, but that might be possible?
If what you want is a list "book","title","page","section","para"
you can use split.
string text = "book//title//page/section/para";
string[] delimiters = { "//", "/" };
string[] result = text.Split(delimiters,StringSplitOptions.RemoveEmptyEntries);
System.Diagnostics.Debug.WriteLine(result);
Assert.IsTrue(result[0].isEqual("book"));
Assert.IsTrue(result[1].isEqual("title"));
Assert.IsTrue(result[2].isEqual("page"));
Assert.IsTrue(result[3].isEqual("section"));
Assert.IsTrue(result[4].isEqual("para"));
Sometin like:
bool lastCharASlash = false;
foreach(char c in text)
{
if(c == #'/')
{
if(lastCharASlash)
{
// my code...
}
lastCharASlash = true;
}
else lastCharASlash = false;
}
You can also do text.Split(#"//")
You could replace // and / with your own words and then find the last index of
string s = "book//title//page/section/para";
s = s.Replace("//", "DOUBLE");
s = s.Replace("/", "SINGLE");
IList<int> doubleIndex = new List<int>();
while (s.Contains("DOUBLE"))
{
int index = s.IndexOf("DOUBLE");
s = s.Remove(index, 6);
s = s.Insert(index, "//");
doubleIndex.Add(index);
}
IList<int> singleIndex = new List<int>();
while (s.Contains("SINGLE"))
{
int index = s.IndexOf("SINGLE");
s = s.Remove(index, 6);
s = s.Insert(index, "/");
singleIndex.Add(index);
}
Remember to first replace double, otherwise you'll get SINGLESINGLE for // instead of DOUBLE. Hope this helps.

Categories

Resources