how To get specific part of a string in c# - c#

I have a string
string a = "(something is there),xyz,(something there)";
and, I use this
string s = "(something is there),xyz,(something there)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);
but I want to use the second part (something there)
how can I do it?

a.Split("(),".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
This will return an array with 3 strings: something is there, xyz, and something there

Not sure what exactly you're doing around this, however this does it in this specific case:
var last = s.Split(',').Last(); // "(something there)"
Or more verbosely for explanation:
var s = "(something is there),xyz,(something there)";
var split = s.Split(','); // [ "(something is there)", "xyz", "(something there)" ]
var last = split.Last(); // "(something there)"
And if you don't want the brackets(en-GB)
var content = last.Trim('(', ')'); // "something there"

If "last" is the same as "second" in this case you can use String.LastIndexOf:
string lastPart = null;
int lastStartIndex = a.LastIndexOf('(');
if (lastStartIndex >= 0)
{
int lastEndIndex = a.LastIndexOf(')');
if (lastEndIndex >= 0)
lastPart = a.Substring(++lastStartIndex, lastEndIndex - lastStartIndex);
}
Here is a solution which extracts all tokens from the string into a List<string>:
int startIndex = -1, endIndex = -1;
var tokens = new List<string>();
while (true)
{
startIndex = a.IndexOf('(', ++endIndex);
if (startIndex == -1) break;
endIndex = a.IndexOf(')', ++startIndex);
if (endIndex == -1) break;
tokens.Add(a.Substring(startIndex, endIndex - startIndex));
}
So now you could use the indexer or Enumerable.ElementAtOrDefault:
string first = tokens[0];
string second = tokens.ElementAtOrDefault(1);
If the list is too small you get null as result. If you just want the last use tokens.Last().

You can use this:
string s = "(something is there),xyz,(something there)";
var start = s.Split(',')[2];
Also You can use:
string s = "(something is there),xyz,(something there)";
Regex regex = new Regex(#"\([^()]*\)(?=[^()]*$)");
Match match = regex.Match("(something is there),xyz,(something there)");
var result = match.Value;

You could use the following if you just want the text:
var s = "(something is there),xyz,(something there)";
var splits = s.Split('(');
var text = splits[2].Trim(')');

If you want to get the text between second '(' and ')' then use the second parameter of IndexOf which sets the starting index for searching
start = s.IndexOf("(", end) + 1;
end = s.IndexOf(")", start);
string secondResult = s.Substring(start, end - start);
If you want to get the string after the last ) use this code:
string otherPart = s.Substring(end+1);

Related

String formatting in C#?

I have some problems to format strings from a List<string>
Here's a picture of the List values:
Now I managed to manipulate some of the values but others not, here's what I used to manipulate:
string prepareStr(string itemToPrepare) {
string first = string.Empty;
string second = string.Empty;
if (itemToPrepare.Contains("\"")) {
first = itemToPrepare.Replace("\"", "");
}
if (first.Contains("-")) {
int beginIndex = first.IndexOf("-");
second = first.Remove(beginIndex, first.Length - beginIndex);
}
return second;
}
Here's a picture of the Result:
I need to get the clear Path without the (-startup , -minimzed , MSRun , double apostrophes).
What am I doing wrong here?
EDIT my updated code:
void getStartUpEntries() {
var startEntries = StartUp.getStartUp();
if (startEntries != null && startEntries.Count != 0) {
for (int i = 0; i < startEntries.Count; i++) {
var splitEntry = startEntries[i].Split(new string[] { "||" }, StringSplitOptions.None);
var str = splitEntry[1];
var match = Regex.Match(str, #"\|\|""(?<path>(?:\""|[^""])*)""");
var finishedPath = match.Groups["path"].ToString();
if (!string.IsNullOrEmpty(finishedPath)) {
if (File.Exists(finishedPath) || Directory.Exists(finishedPath)) {
var _startUpObj = new StartUp(splitEntry[0], finishedPath,
"Aktiviert: ", new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
StartUp.getIcon(finishedPath));
_startUpList.Add(_startUpObj);
}
else {
var _startUpObjNo = new StartUp(splitEntry[0], finishedPath,
"Aktiviert: ", new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
StartUp.getIcon(string.Empty));
_startUpList.Add(_startUpObjNo);
}
}
var _startUpObjLast = new StartUp(splitEntry[0], splitEntry[1],
"Aktiviert: ", new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
StartUp.getIcon(string.Empty));
_startUpList.Add(_startUpObjLast);
}
lstStartUp.ItemsSource = _startUpList.OrderBy(item => item.Name).ToList();
}
You could use a regex to extract the path:
var str = #"0Raptr||""C:\Program Files (x86)\Raptr\raptrstub.exe"" --startup"
var match = Regex.Match(str, #"\|\|""(?<path>(?:\""|[^""])*)""");
Console.WriteLine(match.Groups["path"]);
This will match any (even empty) text (either an escaped quote, or any character which is not a quote) between two quote characters preceeded by two pipe characters.
Similarly, you could simply split on the double quotes as I see that's a repeating occurrence in your examples and take the second item in the split array:
var path = new Regex("\"").Split(s)[1];
This is and update to your logic without using any Regex:
private string prepareStr(string itemToPrepare)
{
string result = null;
string startString = #"\""";
string endString = #"\""";
int startPoint = itemToPrepare.IndexOf(startString);
if (startPoint >= 0)
{
startPoint = startPoint + startString.Length;
int EndPoint = itemToPrepare.IndexOf(endString, startPoint);
if (EndPoint >= 0)
{
result = itemToPrepare.Substring(startPoint, EndPoint - startPoint);
}
}
return result;
}

Split a string containing digits

I'm having a string like,
"abc kskd 8.900 prew"
need to Split this string so that i get the result as "abc kskd" and "8.900 prew"
how can i achieve this with C#?
Get the index of first digit using LINQ then use Substring:
var input = "abc kskd 8.900 prew";
var index = input.Select( (x,idx) => new {x, idx})
.Where(c => char.IsDigit(c.x))
.Select(c => c.idx)
.First();
var part1 = input.Substring(0, index);
var part2 = input.Substring(index);
This should do if you don't need to do something complicated:
var data = "abc kskd 8.900 prew";
var digits = "0123456789".ToCharArray();
var idx = data.IndexOfAny(digits);
if (idx != -1)
{
var firstPart = data.Substring(0, idx - 1);
var secondPart = data.Substring(idx);
}
IndexOfAny is actually very fast.
This could also be modified to separate the string into more parts (using the startIndex parameter), but you didn't ask for that.
straightforward with a regular expression:
var str = "abc kskd 8.900 prew";
var result = Regex.Split(str, #"\W(\d.*)").Where(x => x!="").ToArray();
Try this,
public string[] SplitText(string text)
{
var startIndex = 0;
while (startIndex < text.Length)
{
var index = text.IndexOfAny("0123456789".ToCharArray(), startIndex);
if (index < 0)
{
break;
}
var spaceIndex = text.LastIndexOf(' ', startIndex, index - startIndex);
if (spaceIndex != 0)
{
return new String[] { text.Substring(0, spaceIndex), text.Substring(spaceIndex + 1) };
}
startIndex = index;
}
return new String[] {text};
}
Something similar to what #Dominic Kexel provided, but only if you don't want to use linq.
string[] result = Regex.Split("abc kskd 8.900 prew", #"\w*(?=\d+\.\d)");

String Parse C# to array/SQL database

I have a bunch of files in the format following like this:
20130201:14:58:47 I search: xx ('ID'= (xxxxxxxx) )
20130201:14:58:56 I request: search | For ID | Search
20130201:14:58:56 I search: xx ('ID'= (xxxxxxx) )
Is there something in C# like there is in python called a restkey? I want to grab the first three items (Date time, I (called an action), search/request) and insert each of those into their own column in an SQL table then in the 4th column put the rest of the line.
In python this was quite easy but I couldn't deal with all the hoops I had to jump through to get it to insert into my sql table. So I moved to C# where connection to SSMS is easier.
Although String.Split() is probably the nice and simple way around, I prefer using Regex for this kind of parsing. In this case a pattern like this:
(?<DateTime>\d{8}\:\d{2}\:\d{2}\:\d{2})\s(?<Action>\w)\s(?<SearchOrRequest>search|request)\:\s(?<RestOfTheLine>.*)
Gives you everything you need, nicely grouped into "DateTime", "Action", "SearchOrRequest" and "RestOfLine" match groups.
var pattern = "(?<DateTime>\d{8}\:\d{2}\:\d{2}\:\d{2})\s(?<Action>\w)\s(?<SearchOrRequest>search|request)\:\s(?<RestOfTheLine>.*)";
var regex = new Regex(pattern);
var match = regex.Match(inputString);
var theDate = match.Groups["DateTime"].Value;
var theAction = match.Groups["Action"].Value;
var theChoice = match.Groups["SearchOrRequest"].Value;
var theRest = match.Groups["RestOfTheLine"].Value;
Using string.Split method
string myString = "20130201:14:58:47 I search: xx (\'ID\'= (xxxxxxxx) )"
string[] strarr = myString.split(' ');
string theLetterIVariableThing = strarr[1];
string iddate = strarr[0];
StringBuilder sb = new StringBuilder();
for (int i = 1; i < strarr.Length; i++)
{
sb.Append(strarr[i]);
sb.Append(" ");
}
string trailingText = sb.ToString();
string id = iddate.split(':')[0];
sb.Clear();
for (int i = 1; i < 4; i++)
{
sb.Append(iddate.split(':'))[i];
}
string date = sb.ToString();
I think this will work, but it's probably the long way around.
You can do it using the .NET function String.Split().
Assuming your date string is of fixed-length, this should work:
//string inputStr = "20130201:14:58:47 I search: xx ('ID'= (xxxxxxxx) )";
//string inputStr = "20130201:14:58:56 I request: search | For ID | Search";
string inputStr = "20130201:14:58:56 I search: xx ('ID'= (xxxxxxx) )";
string dateStr = inputStr.Substring(0, 17);
string[] splitStr = inputStr.Substring(18).Split(new char[] { ':' });
string actionStr = splitStr[0].Substring(0, splitStr[0].IndexOf(' '));
string userStr = splitStr[0].Substring(2);
string restStr = splitStr[1].TrimStart();
// print out what we parsed
Console.WriteLine(inputStr);
Console.WriteLine(dateStr);
Console.WriteLine(actionStr);
Console.WriteLine(userStr);
Console.WriteLine(restStr);
Output:
20130201:14:58:56 I search: xx ('ID'= (xxxxxxx) )
20130201:14:58:56
I
search
xx ('ID'= (xxxxxxx) )
I tried a slightly different approach. I created a console program that can convert these files into fully qualified csv files. Then you can import into sql using ssms very easily.
static void Main(string[] args)
{
if (args.Length == 2)
{
using (StreamWriter sw = new StreamWriter(args[1]))
{
using (StreamReader sr = new StreamReader(args[0]))
{
String line;
while ((line = sr.ReadLine()) != null)
{
int index = 0;
int oldIndex = 0;
string dateTime = null;
string action = null;
string task = null;
string details = null;
index = line.IndexOf(' ', oldIndex);
dateTime = line.Substring(oldIndex, index - oldIndex);
oldIndex = index + 1;
index = line.IndexOf(' ', oldIndex);
action = line.Substring(oldIndex, index - oldIndex);
oldIndex = index + 1;
index = line.IndexOf(':', oldIndex);
task = line.Substring(oldIndex, index - oldIndex);
oldIndex = index + 1;
details = line.Substring(oldIndex + 1);
sw.WriteLine("\"{0}\",\"{1}\",\"{2}\",\"{3}\"", dateTime, action, task, details);
}
}
}
}
else
{
Console.WriteLine("Usage: program <input> <output>");
}
}
This is a case where a regular expression is probably the right thing to use.
var testVectors = new[]
{
"20130201:14:58:47 I search: xx ('ID'= (xxxxxxxx) )",
"20130201:14:58:56 I request: search | For ID | Search",
"20130201:14:58:56 I search: xx ('ID'= (xxxxxxx) )"
};
var expression = #"^(?<TimeStamp>[0-9]{8}(:[0-9]{2}){3}) (?<Action>[^ ]+) (?<Type>search|request): (?<Rest>.*)$";
var regex = new Regex(expression);
foreach (var testVector in testVectors)
{
var match = regex.Match(testVector);
Console.WriteLine(match.Groups["Timestamp"]);
Console.WriteLine(match.Groups["Action"]);
Console.WriteLine(match.Groups["Type"]);
Console.WriteLine(match.Groups["Rest"]);
}
The expression used makes some assumptions - what you called action is a sequence of characters not containing any spaces and only search and request are valid values for what I call type. But it should be easy to adopt the expression if any of the assumptions does not hold.

String Search & replacement

I have a string "JohnMarkMarkMark"
I want to replace the "Mark" with "Tom" with two cases
In first case i want to replace only first occurance of "Mark" Result will be: "JohnTomMarkMark"
In the second case i want to replace all the occurance of "Mark" Result will be: "JohnTomTomTom"
Please suggest
Thnaks
string data = "JohnMarkMarkMark";
string resultOne = new Regex("Mark").Replace(data, "Tom", 1);
string resultAll = data.Replace("Mark", "Tom");
For the first case, use IndexOf, Substring and Concat.
For the second case, use Replace.
(1) is:
var inString = "TestMarkMarkMark";
var lookFor = "Mark";
var replaceWith = "Tom";
var length = lookFor.Length;
var first = inString.IndexOf(lookFor);
var newString = inString.Substring(0, first) + replaceWith + inString.Substring(first + length);
Which could be optimized, but I've expanded it out so it's easy to follow.
(2) is trivial - just do inString.Replace("Mark", "Tom");
for case 1 try this
string s = "JohnMarkMarkMark";
Regex x = new Regex("Mark");
MatchCollection m = x.Matches(s);
if (m!=null && m.Count > 0)
{
s = s.Remove(m[0].Index, m[0].Length);
s = s.Insert(m[0].Index,"Tom");
}
for case 2 try s = s.Replace("Mark","Tom");

Strip prefix and value

if I have the string "freq1" or "freq12" and so on, how can I strip out freq and also the number by itself?
string foo = "freq12";
string fooPart = foo.Substring(4); // "12"
int fooNumber = int.parse(fooPart); // 12
if the "freq" part is not constant, then you can use regular expressions:
using System.Text.RegularExpressions;
string pattern = #"([A-Za-z]+)(\d+)";
string foo = "freq12";
Match match = Regex.Match(foo, pattern);
string fooPart = match.Groups[1].Value;
int fooNumber = int.Parse(match.Groups[2].Value);
Is it always going to be the text freq that prepends the number within the string? If so, your solution is very simple:
var str = "freq12";
var num = int.Parse(str.Substring(4));
Edit: Here's a more generic method in the case that the first part of the string isn't always "freq".
var str = "freq12";
int splitIndex;
for(splitIndex = 0; splitIndex < str.Length; splitIndex++)
{
if (char.IsNumeric(str[splitIndex]))
break;
}
if (splitIndex == str.Length)
throw new InvalidOperationException("The input string does not contain a numeric part.");
var textPart = int.Parse(str.Substring(0, splitIndex));
var numPart = int.Parse(str.Substring(splitIndex));
In the given example, textPart should evaluate to freq and numPart to 12. Let me know if this still isn't what you want.
Try something like this:
String oldString = "freq1";
String newString = oldString.Replace("freq", String.Empty);
If you know that the word "freq" will always be there, then you can do something like:
string number = "freq1".Replace("freq","");
That will result in "1".

Categories