I have string like this:
Some data of the string Job ID_Of_the_job some other data of the string
I need to get this ID_Of_the_job
I here this stored in notes string variable
intIndex = notes.IndexOf("Job ")
strJob = notes.Substring(intIndex+4, ???)
I dont know how to get the lenght of this job.
Thanks for help,
Marc
Since you're already using string.IndexOf, here's a solution which builds on that.
Note that there's an overload of String.IndexOf which takes a parameter saying where to start searching.
We've managed to find the beginning of the Job ID, by doing:
int startIndex = notes.IndexOf("Job ") + "Job ".Length;
startIndex is the index of the "I" in "ID_Of_the_job".
We can then use IndexOf again to find the next space -- which will be the space following "ID_Of_the_job":
int endIndex = notes.IndexOf(" ", startIndex);
We can then use Substring:
string jobId = notes.Substring(startIndex, endIndex - startIndex);
Note that there's no error-handling here: if either of the IndexOf fails to find the thing you're looking for, it will return -1, and your code will do strange things. It would be a good idea to handle these cases!
Another, terser solution is to use Regex.
string jobId = Regex.Match(notes, #"Job (\S+)").Groups[1].Value
The regular expression Job (\S+) looks for the text "Job ", followed by 1 or more non-whitespace characters. It puts those non-whitespace characters into a capture group (which becomes Groups[1]), which we can read out.
In this case, jobId will be an empty string if the regex doesn't match.
See these working on dotnetfiddle.
I think I'd make life easy, split the string on spaces and take the string after the array slot that had Job in it:
var notes = "Some data of the string Job ID_Of_the_job some other data of the string";
var bits = notes.Split();
var job = bits[bits.IndexOf("Job") + 1]; //or Array.IndexOf..
If you're on a recent .net and know the job number will occur within the first 10 (say) words, then you can stop splitting after a certain number of words, with e.g. Split(new[]{' '}, 10) - this gives the first 9 words then the rest of the string in the 10th slot which could be a useful performance boost
You could also pull this fairly easily with regex:
var r = new Regex("Job (?<j>[^ ]+?)");
var m = r.Match(notes);
var job = m.Groups["j"].Value;
If you can more accurately define the format of a job number e.g. "it's between 2-3 digits, then a underscore, slash or hyphen, followed by 4 digits", then you don't even have to use Job to locate it, you can put the pattern into the regex:
var r = new Regex(#"(?<j>\d{2,3}[-_\\]\d{4})");
That will pick out a string of the given pattern (\digits {2 to 3 of}, then [hyphen or underscore or slash], then \digits {4 of}).. For example
First step you already did: find the string "Job id ". Second step is to split result by ' ' to extract id.
var input = "Some data of the string Job ID_Of_the_job some other data of the string";
Console.WriteLine(input.Substring(input.IndexOf("Job") + 4).Split(' ')[0]);
Fiddle.
Related
I have a string that I need to separate the product ID from, is this format
shop:?id:556:token:bmgwcGJxZEpnK2RqemhaKzdBYWZjbTVZN0xaOXh5L3pmdDBFZjQrWVVES1pmYVBXVVB6SlFhejBsNndnaHNsUA==
I need to get 556 out of there, and in the case of say 2658 etc also possible.
First index ":" I think
str.Substring(str.LastIndexOf(':') + 1);
But then I dont know how to just break after the match, regex better? any help apprecaited
EDIT
These do the exact same thing, seperating the first numbers out
LINQ:
var test = new string(str.Substring(str.IndexOfAny("0123456789".ToCharArray())).TakeWhile(char.IsDigit).ToArray());
Reggex:
var test = Regex.Match(str, #"\d+").Value;
So bears the question, which is better approach?
If the string format is fixed, use the Split function
string str = "shop:?id:556:token:bmgwcGJxZEpnK2RqemhaKzdBYWZjbTVZN0xaOXh5L3pmdDBFZjQrWVVES1pmYVBXVVB6SlFhejBsNndnaHNsUA==";
int id = Convert.ToInt32(str.Split(':')[2]);
Console.WriteLine(id);
I'd probably use Regex:
var id = Regex.Match(input, #"\?id:(?<x>\d+)").Groups["x"].Value
Decoded, that Regex means "literally match ?id: then start a capturing group called x and capture one or more digits into it"
The returned Match will have a Groups property that we index by x and retrieve the value
If you want it as an int you can int.Parse the result-you won't need a TryParse because the Regex will have only matched digits
If the format of the string is fixed then this would work:
input[9..input.IndexOf(':',10)];
And it would be more performant than Regex or Split
If you wanted a substring that works with a format change, perhaps:
var x = input.IndexOf("?id:") + 4;
var id = input[x..input.IndexOf(':',x+1)];
This will work even if the order of items changes.
string original = "shop:?id:556:token:bmgwcGJxZEpnK2RqemhaKzdBYWZjbTVZN0xaOXh5L3pmdDBFZjQrWVVES1pmYVBXVVB6SlFhejBsNndnaHNsUA==";
string startWithId = original.Substring(original.IndexOf("id:") + 3);
string onlyId = startWithId.Split(':')[0];
Console.WriteLine(onlyId);
I need to get the first char of this string:
String s = "X-4711";
And put it after the number with an ';' , like: 4711;X.
I already tried it with:
String x = s.Split("-")[1] + ";" + s.Split("-")[0];
then I get it, but can I do it better or is this the only possible way?
var items = s.Split ("-");
string x = String.Format ("{0};{1}", items[1], items[0]);
At most this makes it a little more readable and a micro-optimisation of only having to split once.
EDIT :
As some of the comments have pointed out, if you are using C#6 you can make use of String Interpolation to format the string. It does the exact same thing, only looks a little better.
var items = s.Split ("-");
string x = $"{items[1]};{items[0])}";
Not sure what performance you are looking for small string operations, your code is well written and satisfy your needs.
One minor thing you might consider is removing additional split performed on input string.
var subs = s.Split ("-");
String.Format ("{0};{1}", subs [1], subs [0]);
If you are looking single liner (crazy programmer), this might help.
string.Join(";", s.Split('-').Reverse())
String.Substring: Retrieves a substring from this instance. The substring starts at a specified character position and has a specified length.
string sub = input.Substring(0, 1);
string restStr = input.Substring(2, input.length-2);
// string restStr = input.Substring(2); Can also use this instead of above line
string madeStr = restStr + ";" + sub;
You call the Substring method to extract a substring from a string that begins at a specified character position and ends before the end of the string. The starting character position is a zero-based; in other words, the first character in the string is at index 0, not index 1. To extract a substring that begins at a specified character position and continues to the end of the string, call the Substring method.
I have a string that has numbers dash and numbers so it can be
1-2
234-45
23-8
It can be any sequence of any number up to 12 characters.
These all numbers are preceded by a string. I need to extract this string before this sequence begins.
This is a Test1 1-2
This is a test for the first time 234-45
This is a test that is good 23-8
so I need to extract
This is a Test1
This is a test for the first time
This is a test that is good
there is only one space between this string and the sequence.
Is there any way I can extract that string. Split method is not working here.
I forgot to mention that I have numbers/test before the string too so it can be
2123 This is a test for the first time 23-456
or
Ac23 This is a test for the first time 23-457
any help will be appreciated.
Here's one way:
var sample = "2123 This is a Test1 1-2";
// Find the first occurrence of a space, and record the position of
// the next letter
var start = sample.IndexOf(' ') + 1;
// Pull from the string everything starting with the index found above
// to the last space (accounting for the difference from the starting index)
var text = sample.Substring(start, sample.LastIndexOf(' ') - start);
After this, text should equal:
This is a Test1
Wrap it up in a nice little function and send your collection of strings through it:
string ParseTextFromLine(string input)
{
var start = input.IndexOf(' ') + 1;
return input.Substring(start, input.LastIndexOf(' ') - start);
}
This is pretty easy,
string s = "This is a Test1 1-2";
s = s.Substring(0,s.LastIndexOf(" ");
and now s will be "This is a Test1"
Suppose I have a string
Likes (20)
I want to fetch the sub-string enclosed in round brackets (in above case its 20) from this string. This sub-string can change dynamically at runtime. It might be any other number from 0 to infinity. To achieve this my idea is to use a for loop that traverses the whole string and then when a ( is present, it starts adding the characters to another character array and when ) is encountered, it stops adding the characters and returns the array. But I think this might have poor performance. I know very little about regular expressions, so is there a regular expression solution available or any function that can do that in an efficient way?
If you don't fancy using regex you could use Split:
string foo = "Likes (20)";
string[] arr = foo.Split(new char[]{ '(', ')' }, StringSplitOptions.None);
string count = arr[1];
Count = 20
This will work fine regardless of the number in the brackets ()
e.g:
Likes (242535345)
Will give:
242535345
Works also with pure string methods:
string result = "Likes (20)";
int index = result.IndexOf('(');
if (index >= 0)
{
result = result.Substring(index + 1); // take part behind (
index = result.IndexOf(')');
if (index >= 0)
result = result.Remove(index); // remove part from )
}
Demo
For a strict matching, you can do:
Regex reg = new Regex(#"^Likes\((\d+)\)$");
Match m = reg.Match(yourstring);
this way you'll have all you need in m.Groups[1].Value.
As suggested from I4V, assuming you have only that sequence of digits in the whole string, as in your example, you can use the simpler version:
var res = Regex.Match(str,#"\d+")
and in this canse, you can get the value you are looking for with res.Value
EDIT
In case the value enclosed in brackets is not just numbers, you can just change the \d with something like [\w\d\s] if you want to allow in there alphabetic characters, digits and spaces.
Even with Linq:
var s = "Likes (20)";
var s1 = new string(s.SkipWhile(x => x != '(').Skip(1).TakeWhile(x => x != ')').ToArray());
const string likes = "Likes (20)";
int likesCount = int.Parse(likes.Substring(likes.IndexOf('(') + 1, (likes.Length - likes.IndexOf(')') + 1 )));
Matching when the part in paranthesis is supposed to be a number;
string inputstring="Likes (20)"
Regex reg=new Regex(#"\((\d+)\)")
string num= reg.Match(inputstring).Groups[1].Value
Explanation:
By definition regexp matches a substring, so unless you indicate otherwise the string you are looking for can occur at any place in your string.
\d stand for digits. It will match any single digit.
We want it to potentially be repeated several times, and we want at least one. The + sign is regexp for previous symbol or group repeated 1 or more times.
So \d+ will match one or more digits. It will match 20.
To insure that we get the number that is in paranteses we say that it should be between ( and ). These are special characters in regexp so we need to escape them.
(\d+) would match (20), and we are almost there.
Since we want the part inside the parantheses, and not including the parantheses we tell regexp that the digits part is a single group.
We do that by using parantheses in our regexp. ((\d+)) will still match (20), but now it will note that 20 is a subgroup of this match and we can fetch it by Match.Groups[].
For any string in parantheses things gets a little bit harder.
Regex reg=new Regex(#"\((.+)\)")
Would work for many strings. (the dot matches any character) But if the input is something like "This is an example(parantesis1)(parantesis2)", you would match (parantesis1)(parantesis2) with parantesis1)(parantesis2 as the captured subgroup. This is unlikely to be what you are after.
The solution can be to do the matching for "any character exept a closing paranthesis"
Regex reg=new Regex(#"\(([^\(]+)\)")
This will find (parantesis1) as the first match, with parantesis1 as .Groups[1].
It will still fail for nested paranthesis, but since regular expressions are not the correct tool for nested paranthesis I feel that this case is a bit out of scope.
If you know that the string always starts with "Likes " before the group then Saves solution is better.
Hello Everybody i asked this question few hours ago C# get username from string. split
Now i have difficult problem. Trying to get Acid Player And m249 from this string
L 02/28/2012 - 06:14:22: "Acid<1><VALVE_ID_PENDING><CT>"
killed "Player<2><VALVE_ID_PENDING><TERRORIST>" with "m249"
I tried this
int start = Data.ToString().IndexOf('"') + 1;
int end = Data.ToString().IndexOf('<');
var Killer = Data.ToString().Substring(start, end - start);
int start1 = Data.ToString().IndexOf("killed") + 1;
int end1 = Data.ToString().IndexOf('<') + 4;
var Victim = Data.ToString().Substring(start1, end1 - start1);
but its show this exception on last line
Length cannot be less than zero.
Parameter name: length
Does it possible to get Both player name and last string (m249)
Tanks
Here is a simple example of how you can do it with regex. Depending on how much the string varies, this one may work for you. I'm assuming that quotes (") are consistent as well as the text between them. You'll need to add this line at the top:
Using System.Text.RegularExpressions;
Code:
string input = "L 02/28/2012 - 06:14:22: \"Acid<1><VALVE_ID_PENDING><CT>\" killed \"Player<2><VALVE_ID_PENDING><TERRORIST>\" with \"m249\"";
Regex reg = new Regex("[^\"]+\"([^<]+)<[^\"]+\" killed \"([A-Za-z0-9]+)[^\"]+\" with \"([A-Za-z0-9]+)\"");
Match m = reg.Match(input);
if (m.Success)
{
string player1 = m.Groups[1].ToString();
string player2 = m.Groups[2].ToString();
string weapon = m.Groups[3].ToString();
}
The syntax breakdown for the regex is this:
[^\"]+
means, go till we hit a double quote (")
\"
means take the quote as the next part of the string, since the previous term brings us to it, but doesn't go past it.
([^<]+)<
The parenthesis means we are interested in the results of this part, we will seek till we hit a less than (<). since this is the first "group" we're looking to extract, it's referred to as Groups[1] in the match. Again we have the character we were searching for to consume it and continue our search.
<[^\"]+\" killed \"
This will again search, without keeping the results due to no parenthesis, till we hit the next quote mark. We then manually specify the string of (" killed ") since we're interested in what's after that.
([A-Za-z0-9]+)
This will capture any characters for our Group[2] result that are alphanumeric, upper or lowercase.
[^\"]+\"
Search and ignore the rest till we hit the next double quote
with \"
Another literal string that we're using as a marker
([A-Za-z0-9]+)
Same as above, return alphanumeric as our Group[3] with the parenthesis
\"
End it off with the last quote.
Hopefully this explains it. A google for "Regular Expressions Cheat Sheet" is very useful for remembering these rules.
Should be super easy to parse. I recognized that it was CS. Take a look at Valve's documentation here:
https://developer.valvesoftware.com/wiki/HL_Log_Standard#057._Kills
Update:
If you're not comfortable with regular expressions, this implementation will do what you want as well and is along the lines of what you attempted to do:
public void Parse(string killLog)
{
string[] parts = killLog.Split(new[] { " killed ", " with " }, StringSplitOptions.None);
string player1 = parts[0].Substring(1, parts[0].IndexOf('<') - 1);
string player2 = parts[1].Substring(1, parts[1].IndexOf('<') - 1);
string weapon = parts[2].Replace("\"", "");
}
Personally, I would use a RegEx.