C# best way how to parse this String - c#

i have following problem: I have text like this (more than 200 lines):
dsadsadsads(-123|12)sdakodskoakosdakodsadsayxvmyxcmxcym,§§¨§¨§(-43|23)sdadasdas
I want get numbers from text like this:
-123|12
-43|23
Numbers are always in ( ).
What is the fast way, how to get this number. Is possible use some regex? How?
Or brute force foor loop?
Thank you for your reply.

You can use Regex for this purpose.
string str = "dsadsadsads(-123|12)sdakodskoakosdakodsadsayxvmyxcmxcym,§§¨§¨§(-43|23)sdadasdas";
var matches = Regex.Matches(str, #"\(([-+]?\d+\|[-+]?\d+)\)");
foreach (var match in matches)
{
Console.WriteLine(match);
}
Performance test
string str = "dsadsadsads(-123|12)sdakodskoakosdakodsadsayxvmyxcmxcym,§§¨§¨§(-43|23)sdadasdas";
StringBuilder bigstr = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
bigstr.Append(str + "\n");
}
str = bigstr.ToString();
Regex regex = new Regex(#"\(([-+]?\d+\|[-+]?\d+)\)");
Stopwatch w = Stopwatch.StartNew();
var matches = regex.Matches(str);
var count = matches.Count;
w.Stop();
Console.WriteLine(w.Elapsed);
Output in my console. about 0.001 seconds.

Related

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.

Search and count specific words from a text file

i would like to search for a specific set of words (or for now one word) which is "Jude" this is my current code, i can read the file, it separates the words but its just comparing them to a word is the problem. (at the moment it is rigged up to just count words and the output is correct).
Many Thanks
-Fred
String theLine;
string theFile;
int counter = 0;
string[] fields = null;
string delim = " ,.";
Console.WriteLine("Please enter a filename:");
theFile = Console.ReadLine();
System.IO.StreamReader sr =
new System.IO.StreamReader(theFile);
while (!sr.EndOfStream)
{
theLine = sr.ReadLine();
theLine.Trim();
fields = theLine.Split(delim.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
counter += fields.Length;
}
sr.Close();
Console.WriteLine("The word count is {0}", counter);
Console.ReadLine();
}
Using LINQ, you can enumerate the lines of the file, then count the number of occurrences of your word or words in each line and sum the counts together:
Console.WriteLine("Please enter a filename:");
var theFile = Console.ReadLine();
var delim = " ,.".ToCharArray();
var countWords = new HashSet(new[] { "Jude" }.Select(w => w.ToUpperInvariant()));
var count = File.ReadLines(theFile).Select(l => l.Split(delim, StringSplitOptions.RemoveEmptyEntries).Count(w => countWords.Contains(w.ToUpperInvariant()))).Sum();
Console.WriteLine("The word count is {0}", count);
If you prefer #Dai's regex pattern approach, you can use it to count the occurrences in each line, still using LINQ to process the lines and sum the counts:
Console.WriteLine("Please enter a filename:");
var theFile = Console.ReadLine();
var delim = " ,.".ToCharArray();
var countWords = new[] { "Jude" };
var wordPattern = new Regex(#"\b(?:"+String.Join("|", countWords)+#")\b", RegexOptions.Compiled|RegexOptions.IgnoreCase);
var count = File.ReadLines(theFile).Select(l => wordPattern.Matches(l).Count).Sum();
Console.WriteLine("The word count is {0}", count);
Avoid new object allocations inside tight loops, in particular:
Don't use String.Split() as it causes excess string allocation
Also avoid calling ToCharArray() too - you can just cache the results.
Use using() to ensure IDisposable objects are always disposed.
I recommend using a Regex instead:
Regex regex = new Regex( #"\bJude\b", RegexOptions.Compiled | RegexOptions.IgnoreCase );
Int32 count = 0;
using( StreamReader rdr = new StreamReader( theFile ) )
{
String line;
while( ( line = rdr.ReadLine() ) != null )
{
count += regex.Matches( line ).Count;
}
}
The \b escape matches a "word-boundary", such as the start and end of strings and punctuation, so it will match "Jude" in the following examples: "Jude", "Jude foo", "Foo Jude", "Hello. Jude." but not "JudeJude".

Find phone number from given string 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(); ;
}

How can I capitalize every third letter of a string in C#?

How can I capitalize every third letter of a string in C#?
I loop through the whole string with a for loop, but I can't think of the sequence right now.
I suspect you just want something like this:
// String is immutable; copy to a char[] so we can modify that in-place
char[] chars = input.ToCharArray();
for (int i = 0; i < chars.Length; i += 3)
{
chars[i] = char.ToUpper(chars[i]);
}
// Now construct a new String from the modified character array
string output = new string(chars);
That assumes you want to start capitalizing from the first letter, so "abcdefghij" would become "AbcDefGhiJ". If you want to start capitalizing elsewhere, just change the initial value of i.
var s = "Lorem ipsum";
var foo = new string(s
.Select((c, i) => (i + 1) % 3 == 0 ? Char.ToUpper(c) : c)
.ToArray());
You are already looping through the characters inside a string? Then add a counter, increment it on each iteration, and if it is 3, then use .ToUpper(currentCharacter) to make it upper case. Then reset your counter.
You could just use a regular expression.
If the answer is every third char then you want
var input = "sdkgjslgjsklvaswlet";
var regex = new Regex("(..)(.)");
var replacement = regex.Replace(input, delegate(Match m)
{
return m.Groups[1].Value + m.Groups[2].Value.ToUpper();
});
If you want every third character, but starting with the first you want:
var input = "sdkgjslgjsklvaswlet";
var regex = new Regex("(.)(..)");
var replacement = regex.Replace(input, delegate(Match m)
{
return m.Groups[1].Value.ToUpper() + m.Groups[2].Value;
});
If you want a loop, you can convert to a character array first, so you can alter the values.
For every third character:
var x = input.ToCharArray();
for (var i = 2; i <x.Length; i+=3) {
x[i] = char.ToUpper(x[i]);
}
var replacement = new string(x);
For every third character from the beginning:
var x = input.ToCharArray();
for (var i = 0; i <x.Length; i+=3) {
x[i] = char.ToUpper(x[i]);
}
var replacement = new string(x);

How can I replace a specific word in C#?

Consider the following example.
string s = "The man is old. Them is not bad.";
If I use
s = s.Replace("The", "##");
Then it returns "## man is old. ##m is not bad."
But I want the output to be "## man is old. Them is not bad."
How can I do this?
Here's how you'd use a regex, which would handle any word boundaries:
Regex r = new Regex(#"\bThe\b");
s = r.Replace(s, "##");
I made a comment above asking why the title was changed to assume Regex was to be used.
I personally try to not use Regex because it's slow. Regex is great for complex string patterns, but if string replacements are simple and you need some performance out of it, I'll try and find a way without using Regex.
Threw together a test. Running a million replacments with Regex and string methods.
Regex took 26.5 seconds to complete, string methods took 8 seconds to complete.
//Using Regex.
Regex r = new Regex(#"\b[Tt]he\b");
System.Diagnostics.Stopwatch stp = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++)
{
string str = "The man is old. The is the Good. Them is the bad.";
str = r.Replace(str, "##");
}
stp.Stop();
Console.WriteLine(stp.Elapsed);
//Using String Methods.
stp = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 1000000; i++)
{
string str = "The man is old. The is the Good. Them is the bad.";
//Remove the The if the stirng starts with The.
if (str.StartsWith("The "))
{
str = str.Remove(0, "The ".Length);
str = str.Insert(0, "## ");
}
//Remove references The and the. We can probably
//assume a sentence will not end in the.
str = str.Replace(" The ", " ## ");
str = str.Replace(" the ", " ## ");
}
stp.Stop();
Console.WriteLine(stp.Elapsed);
s = s.Replace("The ","## ");
C# console Application
static void Main(string[] args)
{
Console.Write("Please input your comment: ");
string str = Console.ReadLine();
string[] str2 = str.Split(' ');
replaceStringWithString(str2);
Console.ReadLine();
}
public static void replaceStringWithString(string[] word)
{
string[] strArry1 = new string[] { "good", "bad", "hate" };
string[] strArry2 = new string[] { "g**d", "b*d", "h**e" };
for (int j = 0; j < strArry1.Count(); j++)
{
for (int i = 0; i < word.Count(); i++)
{
if (word[i] == strArry1[j])
{
word[i] = strArry2[j];
}
Console.Write(word[i] + " ");
}
}
}

Categories

Resources