Parse string to different variables c# - c#

I've got a string fdf=232232&lid=19974832&number=1&aa_result1_1=someId1&aa_resuuuuuult2_2=someId2&aa_resuuuult3_3=someId3
and if aa exists I need to take values and add them to dictionary like:
var dict = extendedIds.Add("result1", new Dictionary<string, int[]>()
{
{
"someId1",
new int[]{ 1 }
}, ...
});
however I am having a difficult time deciding how to parse it properly? I need to accept multiple aa values (the ones that come as resultN, someIdN and a number (which is the number after resultN_NUMBER).
I tried to use substring but that doesn't work as I dont't now the length of word result
Basically it is
var parameters = $"pam=805700&laaid=19974832&kpm=1&{HttpUtility.UrlEncode("aa_{result}_{number}={id}&aa_{result}_{number}={id}&aa_{result}_{number}={id}", Encoding.UTF8)}";
So I decode it and get string:
var decoded = input.ToString().UrlDecode();
I need to accept multiple aa values, so in this example there would be three values, two of them comes from in bertween _ one after = but I wonder how to take these values then there could be something else also split by _...
also I could var parsed = HttpUtility.ParseQueryString(decoded); parse to NameValueCollection. but I can't use parsed.GetValues("aa") because the key would be e.g. aa_result1_1 and I never know beforehand what it is

this is a query string, you can use HttpUtility.ParseQueryString to parse it
see
https://learn.microsoft.com/en-us/dotnet/api/system.web.httputility.parsequerystring?view=net-5.0

Would this set you on the right track?
var qs = "fdf=232232&lid=19974832&number=1&aa_result1_1=someId1&aa_resuuuuuult2_2=someId2&aa_resuuuult3_3=someId3";
var nvc = System.Web.HttpUtility.ParseQueryString(qs);
foreach (var key in nvc.AllKeys.Where(k => k.StartsWith("aa")))
{
var id = nvc[key];
var parts = key.Split('_');
var result = parts[1];
var number = parts[2];
Console.WriteLine($"result = '{result}', number = '{number}' => id = '{id}'");
}
Use ParseQueryString to convert your string into a NameValueCollection.
Then use each key that starts with "aa"
Get its value - this is your "id"
Split the key on the _
Ignore the first part (which would be "aa") and use the next two parts
Of course you would want to add some safety: I now assume that there always are 3 parts in that key. Plus you want to do something useful with the results.
The above code prints this
result = 'result1', number = '1' => id = 'someId1'
result = 'resuuuuuult2', number = '2' => id = 'someId2'
result = 'resuuuult3', number = '3' => id = 'someId3'

Related

Dynamic linq backslash in where clause

I use System.Linq.Dynamic to query entities with dynamic 'where' expressions. I'm querying object that has property "newValue" of string type. Exemplary value would be : "{\"ProcessId\":764, \"ProcessLength\":1000}".
I can't use == because I want to find all hits where the property contains "ProcessId:764", regardless on the rest of the string. The thing is, that stored string contains escape sign "\" and double quotes and I can't figure out what it should like exactly..
dbContext.Processes.Where("#newValue.Contains(\"ProcessId\":764\")") brings error, however dbContext.Processes.Where("#newValue.Contains(\":764\")") works correctly. I guess it must be something with backslashes or double quotes in my query but can't figure it out on my own..
There are two things to note here:
If you know at compile time the column that should be queried (i.e., newValue), just use standard Linq: var list = items.Where(i => i.NewValue.Contains("904")).ToList().
If you do want to use dyanmic Linq, What you'd usually want is to apply Where on some column, e.g. Where("SomeColumn.Contains("something")"), or Where("SomeColumn.Contains(#0)", new string[] {"something"}).
So, in your case, this should work: items.Where("newValue.Contains(\"904\")").
Doing Where("#newValue.Contains("something")") doesn't really make sense, since #newValue would be parsed as a string literal. See also this comment on a similiar question.
Here' a quick example:
public static void Main(string[] args)
{
var items = new []
{
new { Id = "1", Title = "ProcessId: 123"},
new { Id = "4", Title = "ProcessId: 456"},
new { Id = "7", Title = "ProcessId: 789"},
}.ToList();
// returns null, because the string "Title" doesn't contain the string "7"
var res1 = items.Where("#0.Contains(\"7\")", new string[] {"Title"}).FirstOrDefault();
// works - returns the 3rd element of the array
var res2a = items.Where("Title.Contains(#0)", new string[] {"ProcessId: 789"}).FirstOrDefault();
var res2b = items.Where("Title.Contains(\"ProcessId: 789\")").FirstOrDefault();
}
#HeyJude Thanks for the effort, but I still can't get it to work. It has somehow gone wronger and now I can't even fetch correct rows giving only ProcessId number..
Let me give you more detailed description of my setup. In the database there's a table with column "NewValue", I use this column to store json string of current (for the time of creating row in the table) representation of some object e.g. object Process. So the column stores for example string of {"ProcessId":904,"ProcessLength":1000}. To fetch this data from db I create collection of table's records: var items = (from l in db.JDE_Logs
join u in db.JDE_Users on l.UserId equals u.UserId
join t in db.JDE_Tenants on l.TenantId equals t.TenantId
where l.TenantId == tenants.FirstOrDefault().TenantId && l.Timestamp >= dFrom && l.Timestamp <= dTo
orderby l.Timestamp descending
select new //ExtLog
{
LogId = l.LogId,
TimeStamp = l.Timestamp,
TenantId = t.TenantId,
TenantName = t.TenantName,
UserId = l.UserId,
UserName = u.Name + " " + u.Surname,
Description = l.Description,
OldValue = l.OldValue,
NewValue = l.NewValue
});. Then I query it to find matching rows for given ProcessId number e.g. query = "#NewValue.Contains(\"904,)\")";
items = items.Where(query);
This should fetch back all records where NewValue column contains the query string, but this doesn't work. It compiles and 'works' but no data are fetched or fetched are only those records where 904 appears later in the string. Sounds stupid but this is what it is.
What should the query string look like to fetch all records containing "ProcessId":904?

Get everything after Slash c#

I'm trying to figure out the best way to get everything before the / character in a string. Some example strings are below.
var url = dr.FindElements(By.XPath("//*[#id=\"u_0_3\"]/div/h1/a"));
foreach (var item in url)
{
if (item.GetAttribute("href").ToString().Contains("https://www.facebook.com/"))
{
listBox4.Items.Add("here");
}
}
the href is like that = "http://facebook.com/xxx"
want the xxx which is username want to get it alone in my listbox without the rest of the url
If you're at the point where you've got the string you want to work with, here are two ways to do this:
Split the string by / and take the last part
var stringToProcess = "https://www.facebook.com/ProfileName";
var partsOfString = stringToProcess.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var profileName = partsOfString.Last();
Use the Uri class to extract the last part
var stringToProcess = "https://www.facebook.com/ProfileName";
var stringToProcessAsUri = new Uri(stringToProcess);
var profileNameFromUri = stringToProcessAsUri.Segments.Last();
This is the "strictly better" way as it will give you a clean result even if the profile address has a query string attached to it, i.e:
var stringToProcess = "https://www.facebook.com/ProfileName?abc=def";
var stringToProcessAsUri = new Uri(stringToProcess);
var profileNameFromUri = stringToProcessAsUri.Segments.Last();
You'll still have the variable profileNameFromUri returned containing only ProfileName

Extract a substring from a string in C#

How can I extract the substring "John Woo" from the below string in C#
CN=John Woo,OU=IT,OU=HO,DC=ABC,DC=com
Thanks !
You could use a Lookup<TKey, TElement>:
string text = "CN=John Woo,OU=IT,OU=HO,DC=ABC,DC=com";
var keyValues = text.Split(',')
.Select(s => s.Split('='))
.ToLookup(kv => kv[0], kv => kv.Last());
string cn = keyValues["CN"].FirstOrDefault(); // John Woo
// or, if multiple values with the same key are allowed (as suggested in the given string)
string dc = string.Join(",", keyValues["DC"]); // ABC,com
Note that you neither get an exception if the key is not present(as in a dictionary) nor if the key is not uniqe (as in a dictionary). The value is a IEnumerable<TElement>.
Try this
var regex = new Regex("CN=(?<mygroup>.*?),");
var match = regex.Match("CN=John Woo,OU=IT,OU=HO,DC=ABC,DC=com");
if(match.Success)
{
string result = match.Groups["mygroup"].Value;
}
Try this (this is a non generic answer) :
var name = str.Split(',').Where(n => n.StartsWith("CN=")).FirstOrDefault().Substring(3);
Something like this
var s = "CN=John Woo,OU=IT,OU=HO,DC=ABC,DC=com";
// this give you a enumarable of anonymous key/value
var v = s.Split(',')
.Select(x => x.Split('='))
.Select(x => new
{
key = x[0],
value = x[1],
});
var name = v.First().value; // John Woo
You can firstly split the string by the commas to get an array of strings, each of which is a name/value pair separated by =:
string input = "CN=John Woo,OU=IT,OU=HO,DC=ABC,DC=com";
var nameValuePairs = input.Split(new[] {','});
Then you can split the first name/value pair like so:
var nameValuePair = nameValuePairs[0].Split(new[]{'='});
Finally, the value part will be nameValuePair[1]:
var value = nameValuePair[1];
(No error handling shown above - you would of course have to add some.)
I created the below code of my own and finally got the substring I needed. The below code works for every substring that I want to extract that falls after "CN=" and before first occurrence of ",".
string name = "CN=John Woo,OU=IT,OU=HO,DC=ABC,DC=com";
int index1 = name.IndexOf("=") + 1;
int index2 = name.IndexOf(",") - 3;
string managerName = name.Substring(index1, index2);
The Result was "John Woo"
Thanks all for your help...

Getting values from a list using foreach

I have list that have values like"
[0] = "{ id = ES10209005, views = 501 }"
[1] = "{ id = HYT0209005, views = 5678}"
[3] = "{ id = POI0209005, views = 4568}"
I would like to pass the values(id,views) to a method using a for each loop.
method(id,views)
Something like:
foreach (string v in updatereponse)
{
method()
}
How do I isolate each value(id,views) from each row in the list then pass it to the method?
The list contains just a bunch of strings, anything based on this to fix the problem would be just a workaround (e.g. string parsing). You should really switch to a strongly typed model, e.g. define a class ViewCount:
public class ViewCount
{
public string Id {get;set;}
public int Views {get;set;}
}
You can then use a List<ViewCount> populate the list:
List<ViewCount> viewcounts = new List<ViewCount>();
viewCounts.Add(new ViewCount() { Id = "ES10209005", Views = 501 });
Since each ViewCount instance has Id and Views properties you can now do the proper thing:
foreach (var item in updatereponse)
{
method(item.Id, item.Views);
}
If you are saving this data in a file, an alternative would be to use XML instead of custom strings, then you could use Linq to XML to populate a List<ViewCount>, e.g. using a simple XML like this:
<ViewCounts>
<ViewCount id="ES10209005" views="501" />
</ViewCounts>
You can then load your list:
XElement viewXml = XElement.Load("test.xml");
List<ViewCount> viewCounts = viewXml.Descendants("ViewCount")
.Select(x => new ViewCount()
{
Id = (string)x.Attribute("id"),
Views = (int)x.Attribute("views")
}).ToList();
foreach (string v in updateresponse)
{
var values = v.Split(",");
var id = values[0].Replace("{ id = ", "").Trim();
var view = values[1].Replace("views = ", "").("}","").Trim();
method(id, value);
}
Here's another way...you may want to add error checking:
String Data = "{ id = ES10209005, views = 501 }";
String[] Segments = Data.Split(new char[] { ' ', ',' });
string ID = Segments[3];
int views = int.Parse(Segments[7]);
Assuming the structure of your String is like you showed us always, this can work for you.
// First split id and views part.
String[] firstSplit = v.Split(',');
// Get the respected value for each part.
String id = firstSplit[0].Split('=')[1].Trim();
String views = firstSplit[1].Split('=')[1].Trim().Replace("}","");
You can use String methods to retrieve the items (use Split and SubString for example) or you can use a regular expression.
E.g.
var list = UpdateResponse[0].Split("=,} ") ;
will result in a list split by all these characters (including space).
Then check the correct indices to use (use a debugger for that). Then you get something like:
var id = list[5];
var views = list[8];
(note: check the indices 5 or 8, they are just a guess).

Reading Text file with Linq with 2 patterns

I need to read a text file like this
MyItemName = Description # MoreInfo
Now I need to convert this 3 fields in to a table. using the '=' and '#' as pattern.
Just splitting on = and # - this returns and IEnumerable of an anonymous class with the properties you are interested in:
var items = File.ReadAllLines(fileName)
.Skip(1) //Skip header
.Where( line => !string.IsNullOrWhiteSpace(line))
.Select(line =>
{
var columns = line.Split('=', '#');
return new
{
ItemName = columns[0].Trim(),
Description = columns[1].Trim(),
MoreInfo = columns[2].Trim()
};
});
This approach would require the separator tokens to be used as separators exclusively - if they do occur in any of the fields, this will mess up everything and void this approach.
if you really want to use linq for it...
It doesn't look very nice and it doesn't create a table, but you get the point:
from line in File.ReadAllLines(filename)
let eqPos = line.IndexOf('=')
let atPos = line.IndexOf('#')
select new {
Name = line.Substring(0, eqPos).Trim(),
Desc = line.Substring(eqPos + 1, atPos - (eqPos + 1)).Trim(),
Info = line.Substring(atPos + 1).Trim()
}

Categories

Resources