C# IndexOf (Read from resource.resx) - c#

I created config file with some texts and this file i added to resource.resx. Now i created string for this text.
// String will be contains all texts from resource file
string TextFromResources = Resource.konfigurace;
TextFromResources - > View:
#################
# Settings
#################
RealmID = 1
#################
For next step i need use function "IndexOf".
int value = TextFromConfig.IndexOf("RealmID");
value = TextFromConfig.IndexOf('=');
value2 = TextFromConfig.IndexOf("/r/n");
RealmID = int.Parse(TextFromConfig.Substring(value, value2));
I need that realmID return me int value "1", but now its return me nothing. Please, can you help with my problem?
If index will be correctly so it will be return me value "1" nothing more.

Ah, the substring needs to start after value. Here's a simplified version of your example that works for me:
var text = "RealmID = 1\r\n";
var value = text.IndexOf('=');
var value2 = text.IndexOf("\r\n", value);
var id = int.Parse(text.Substring(value + 1, value2 - value));
Also, I modified the IndexOf call for getting value2 so that it searches for "\r\n" after the location of '='.
Another option is to use a regular expression to find the RealmID value.
var regex = new Regex(#"RealmID = (\d+)");
var match = regex.Match(text);
int realmID = int.Parse(match.Groups[1].Value);

Related

How to get substrings from an Xpath using C#?

I have an Xpath property inside of a JSON file and I'd like to get two substrings from this Xpath to assisting these substrings into two variables.
The JSON object is as follows;
{
'selectGateway':'0',
'waitingTime':'20000',
'status':'200',
'correlationID':'1',
'matchString':[{'xpath':'/whitelist/locations/location/var-fields/var-field[#key="whitelist-entry" and #value="8.0440147AA44A80"]','value':''}],
'matchInteger':[],
'matchSortedList':[]
}
This is my attempt so far it's working properly, I'm just looking for a way to do this more dynamically and in a better way if it's possible.
int firstStringPositionForKey = matchString[index].xpath.IndexOf("#key=\"");
int secondStringPositionForKey = matchString[index].xpath.IndexOf("\" and");
string betweenStringForKey = matchString[index].xpath.Substring(firstStringPositionForKey+6, secondStringPositionForKey-firstStringPositionForKey-6);
int firstStringPositionForValue = matchString[index].xpath.IndexOf("#value=\"");
int secondStringPositionForValue = matchString[index].xpath.IndexOf("\"]");
string betweenStringForValue = matchString[index].xpath.Substring(firstStringPositionForValue+8, secondStringPositionForValue-firstStringPositionForValue-8);
I expect the output to be like:
key is : whitelist-entry
value is : 8.0440147AA44A80
I believe you are getting value of xPath in matchString[index].xpath, so here is the solution
//Test is nothing but your xPath
string test = "/whitelist/locations/location/var-fields/var-field[#key=\"whitelist-entry\" and #value=\"8.0440147AA44A80\"]";
//Split your string by '/' and get last element from it.
string lastElement = test.Split('/').LastOrDefault();
//Use regex to get text present in "<text>"
var matches = new Regex("\".*?\"").Matches(lastElement);
//Remove double quotes
var key = matches[0].ToString().Trim('\"');
var #value = matches[1].ToString().Trim('\"');;
//Print key and value
Console.WriteLine("Key is: ${key}");
Console.WriteLine("Value is: ${value}");
Output:
Key is: whitelist-entry
Value is: 8.0440147AA44A80
.net fiddle
Using Regex (Link to formula)
var obj = JObject.Parse("your_json");
var xpath = ((JArray)obj["matchString"])[0]["xpath"].Value<string>();
string pattern = "(?<=key=\")(.*?)(?=\").*(?<=value=\")(.*?)(?=\")";
var match = new Regex(pattern).Match(xpath);
string key = match.Groups[1].Value;
string value = match.Groups[2].Value;

Best way to use Regex and int's

I have an application that loops through a group of documents and if a value is detected, then the user receives a prompt to replace this value. My current code looks like the following;
if (alllines[i].Contains("$"))
{
// prompt
int dollarIndex = alllines[i].IndexOf("%");
string nextTenChars = alllines[i].Substring(dollarIndex + 1, 18);
string PromtText = nextTenChars.Replace("%", "").Replace("/*", "").Replace("*/", "");
string promptValue = CreateInput.ShowDialog(PromtText, fi.FullName);
if (promptValue.Equals(""))
{
}
else
{
alllines[i] = alllines[i].Replace("$", promptValue);
File.WriteAllLines(fi.FullName, alllines.ToArray());
}
}
As you can see the prompt box displays 18 characters after the index which in this case is % however, if there are not 18 characters then the application crashes. What I want to do is use regex but I am unsure of how to apply this in the codes current state.
If I use the below I get the error Cannot convert from int to string any help would be appreciated.
Regex regex = new Regex(#"(\$.{1,10})");
var chars = regex.Matches(dollarIndex);
This should work
Regex regex = new Regex(#"(/*%.{1,50})");
var chars = regex.Match(alllines[i]).ToString();
string promptValue = CreateInput.ShowDialog(PromtText, fi.FullName);

How to replace multiple texts in a file in c#?

I am automating a process using c#. My script would look like below,
UPDATE Table
SET param_val = REPLACE(param_val,'Proxy430/','Proxy440/')
WHERE param_key = 'PROXY_URL';
UPDATE Table
SET param_val = REPLACE (param_val, '.420/', '.430/')
WHERE param_val LIKE '%.420/%';
For every month, we will upgrade the version like 44 in place of 43 and 43 in place of 42 and run this script. To automate, i've written C# code and used below code
string text = File.ReadAllText(filePath);
text.Replace(oldvale, newvalue);
File.WriteAllText(filepath, text);
But, issue is it can replace one word only. How to replace two texts in a file. In my case, Proxy430 should be replaced as Proxy440 and Proxy440 into Proxy450 in single shot.
How to achieve this?
If you call replace in the right order you can accomplish two replacements on a single line.
string TestString = #"UPDATE Table
SET param_val = REPLACE(param_val, 'Proxy430/', 'Proxy440/')
WHERE param_key = 'PROXY_URL';
UPDATE Table
SET param_val = REPLACE(param_val, '.420/', '.430/')
WHERE param_val LIKE '%.420/%'; ";
const string oldFrom = "Proxy430";
const string oldTo = "Proxy440";
const string newFrom = "Proxy440";
const string newTo = "Proxy450";
string result = TestString.Replace(newFrom, newTo).Replace(oldFrom, oldTo);
Console.WriteLine(result);
The output is:
UPDATE Table
SET param_val = REPLACE(param_val, 'Proxy440/', 'Proxy450/')
WHERE param_key = 'PROXY_URL';
UPDATE Table
SET param_val = REPLACE(param_val, '.420/', '.430/')
WHERE param_val LIKE '%.420/%';
The problem is you don't assign the return value of Replace method. Replace doesn't modify this string it returns replaced string.
Change it like this:
text = text.Replace(oldvale, newvalue);
Here's a fiddle.
If the things are really sequential numerically, you can do something like this:
string text = File.ReadAllText(filePath);
for (int i=lowestVersion; i < highestVersion; i++)
{
var oldValue = i.ToString() + "0";
var newValue = (i+1).ToString() + "0";
text.Replace(oldValue , newvalue);
}
File.WriteAllText(filepath, text);
You can create a custom method for this.
private void MultipleReplace(string text, string[] oldValues, string[] newValues)
{
for (int i = 0; i < old.Length; i++)
{
text = text.replace(oldValues[i], newValues[i]);
}
}
You need to consider the order of replacements, because once you replace Proxy430 by Proxy440, you can no longer replace Proxy440 by Proxy450, because that'll also replace the values updated in the previous iteration.
Example:
string text = File.ReadAllText(filePath);
string[] oldValues = { "Proxy440", "Proxy430" };
string [] newValues = { "Proxy450", "Proxy440" };
MultipleReplace(text, oldValues, newValues);
File.WriteAllText(filepath, text);

how to use regex class for string maniplations

I am working on string maniplations using regex.
Source: string value = #"/webdav/MyPublication/Building%20Blocks/folder0/folder1/content_1.xml";
output required:
Foldername: folder1
content name: content
folderpath:/webdav/MyPublication/Building%20Blocks/folder0/folder1/
I am new to this, can any one say how it can be done using regex.
Thank you.
The rules you need seem to be the following:
Folder name = last string preceding a '/' character but not containing a '/' character
content name = last string not containing a '/' character until (but not including) a '_' or '.' character
folderpath = same as folder name except it can contain a '/' character
Assuming the rules above - you probably want this code:
string value = #"/webdav/MyPublication/Building%20Blocks/folder0/folder1/content_1.xml";
var foldernameMatch = Regex.Match(value, #"([^/]+)/[^/]+$");
var contentnameMatch = Regex.Match(value, #"([^/_\.]+)[_\.][^/]*$");
var folderpathMatch = Regex.Match(value, #"(.*/)[^/]*$");
if (foldernameMatch.Success && contentnameMatch.Success && folderpathMatch.Success)
{
var foldername = foldernameMatch.Groups[1].Value;
var contentname = contentnameMatch.Groups[1].Value;
var folderpath = folderpathMatch.Groups[1].Value;
}
else
{
// handle bad input
}
Note that you can also combine these to become one large regex, although it can be more cumbersome to follow (if it weren't already):
var matches = Regex.Match(value, #"(.*/)([^/]+)/([^/_\.]+)[_\.][^/]*$");
if (matches.Success)
{
var foldername = matches.Groups[2].Value;
var contentname = matches.Groups[3].Value;
var folderpath = matches.Groups[1].Value + foldername + "/";
}
else
{
// handle bad input
}
You could use named captures, but you're probably better off (from a security and implementation aspect) just using the Uri class.
I agree with Jeff Moser on this one, but to answer the original question, I believe the following regular expression would work:
^(\/.+\/)(.+?)\/(.+?)\.
edit: Added example.
var value = "/webdav/MyPublication/Building%20Blocks/folder0/folder1/content_1.xml";
var regex = Regex.Match(value, #"^(\/.+\/)(.+?)\/(.+?)\.");
// check if success
if (regex.Success)
{
// asssign the values from the regular expression
var folderName = regex.Groups[2].Value;
var contentName = regex.Groups[3].Value;
var folderPath = regex.Groups[1].Value;
}

Splitting a string which contain multiple symbols to get specific values

I cannot believe I am having trouble with this following string
String filter = "name=Default;pattern=%%;start=Last;end=Now";
This is a short and possibly duplicate question, but how would I split this string to get:
string Name = "Default";
string Pattern = "%%" ;
string start = "Last" ;
string end = "Now" ;
Reason why I ask is my deadline is very soon, and this is literally the last thing I must do. I'm Panicking, and I'm stuck on this basic command. I tried:
pattern = filter.Split(new string[] { "pattern=", ";" },
StringSplitOptions.RemoveEmptyEntries)[1]; //Gets the pattern
startDate = filter.Split(new string[] { "start=", ";" },
StringSplitOptions.RemoveEmptyEntries)[1]; //Gets the start date
I happen to get the pattern which I needed, but as soon as I try to split start, I get the value as "Pattern=%%"
What can I do?
Forgot to mention
The list in this string which needs splitting may not be in any particular order . this is a single sample of a string which will be read out of a stringCollection (reading these filters from Properties.Settings.Filters
Using string.Split this is a two stage process.
In the first case split on ; to get an array of keyword and value pairs:
string[] values = filter.Split(';');
Then loop over the resultant list splitting on = to get the keywords and values:
foreach (string value in values)
{
string[] pair = value.Split('=');
string key = pair[0];
string val = pair[1];
}
String filter = "name=Default;pattern=%%;start=Last;end=Now";
string[] temp = filter.Split('=');
string name = temp[1].Split(';')[0];
string pattern = temp[2].Split(';')[0];
string start = temp[3].Split(';')[0];
string end = temp[4].Split(';')[0];
This should do the trick:
string filter = "name=Default;pattern=%%;start=Last;end=Now";
// Make a dictionary.
var lookup = filter
.Split(';')
.Select(keyValuePair => keyValuePair.Split('='))
.ToDictionary(parts => parts[0], parts => parts[1]);
// Get values out of the dictionary.
string name = lookup["name"];
string pattern = lookup["pattern"];
string start = lookup["start"];
string end = lookup["end"];
The start date ends up at the thrird position in the array:
startDate = filter.Split(new string[] { "start=", ";" }, StringSplitOptions.RemoveEmptyEntries)[2];
Instead of splitting the string once for each value, you might want to split it into the separate key-value pairs, then split each pair:
string[] pairs = filter.Split(';');
string[] values = pairs.Select(pair => pair.Split('=')[1]).ToArray();
string name = values[0];
string pattern = values[1];
string start = values[2];
string end = values[3];
(This code of course assumes that the key-value pairs always come in the same order.)
You could also split the string into intersperced array, so that every other item is a key or a value:
string[] values = filter.Split(new string[] { "=", ";" }, StringSplitOptions.None);
string name = values[1];
string pattern = values[3];
string start = values[5];
string end = values[7];
Edit:
To handle key-values in any order, make a lookup from the string, and pick values from it:
ILookup<string, string> values =
filter.Split(';')
.Select(s => s.Split('='))
.ToLookup(p => p[0], p => p[1]);
string name = values["name"].Single();
string pattern = values["pattern"].Single();
string start = values["start"].Single();
string end = values["end"].Single();
You can use SingleOrDefault if you want to support values being missing from the string:
string name = values["name"].SingleOrDefault() ?? "DefaultName";
The lookup also supports duplicate key-value pairs. If there might be duplicates, just loop through the values:
foreach (var string name in values["name"]) {
// do something with the name
}
Well I tried something like this:
var result = "name=Default;pattern=%%;start=Last;end=Now".Split(new char[]{'=',';'});
for(int i=0;i<result.Length; i++)
{
if(i%2 == 0) continue;
Console.WriteLine(result[i]);
}
and the output is:
Default
%%
Last
Now
Is this what you want?
You see, the thing is now that your Split on filter a second time still starts from the beginning of the string, and it matches against ;, so since the string hasn't changed, you still retrieve previous matches (so your index accessor is off by X).
You could break this down into it's problem parts, such that:
var keyValues = filter.Split(';');
var name = keyValues[0].Split('=')[1];
var pattern = keyValues[1].Split('=')[1];
var start = keyValues[2].Split('=')[1];
var end = keyValues[3].Split('=')[1];
Note that the above code is potentially prone to error, and as such should be properly altered.
You can use the following:
String filter = "name=Default;pattern=%%;start=Last;end=Now";
string[] parts = filter.Split(';');
string Name = parts[0].Substring(parts[0].IndexOf('=') + 1);
string Pattern = parts[1].Substring(parts[1].IndexOf('=') + 1);
string start = parts[2].Substring(parts[2].IndexOf('=') + 1);
string end = parts[3].Substring(parts[3].IndexOf('=') + 1);
Use this:
String filter = "name=Default;pattern=%%;start=Last;end=Now";
var parts = filter.Split(';').Select(x => x.Split('='))
.Where(x => x.Length == 2)
.Select(x => new {key = x[0], value=x[1]});
string name = "";
string pattern = "";
string start = "";
string end = "";
foreach(var part in parts)
{
switch(part.key)
{
case "name":
name = part.value;
break;
case "pattern":
pattern = part.value;
break;
case "start":
start = part.value;
break;
case "end":
end = part.value;
break;
}
}
If you don't need the values in named variables, you only need the second line. It returns an enumerable with key/value pairs.
My solution has the added benefits that the order of those key/value pairs in the string is irrelevant and it silently ignores invalid parts instead of crashing.
I found a simple solution on my own too. Most of your answers would have worked if the list would have been in the same order every single time, but it wont be. the format however, will always stay the same. The solution is a simple iteration using a foreach loop, and then checking if it starts with a certain word, namely, the word I am looking for, like Name, Pattern etc.
Probably not the most cpu efficient way of doing it, but it is C# for dummies level. Really brain-fade level.
Here is my beauty.
foreach (string subfilter in filter.Split(';')) //filter.Split is a string [] which can be iterated through
{
if (subfilter.ToUpper().StartsWith("PATTERN"))
{
pattern = subfilter.Split('=')[1];
}
if (subfilter.ToUpper().StartsWith("START"))
{
startDate = subfilter.Split('=')[1];
}
if (subfilter.ToUpper().StartsWith("END"))
{
endDate = subfilter.Split('=')[1];
}
}

Categories

Resources