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
Related
How can I parse the INT contents of this string, and add to List ?
Files[file1.jpg[2066654],file2.png[234235],file3.gif[56476788]]
That way I can call fields, like list.Filename, list.Filesize
Its a custom string im using to group files in a txt file, so I want to extract these values out : filename (with extension), and size (int)
How can I do this? I've tried
var filename = str.Substring(str.LastIndexOf('Files[') + 1).str.Substring(str.LastIndexOf(']'));
But I have no way of getting this especially in this type of format. Any suggestions?
Thanks!
Regex is your friend here.
Try this:
var regex = new Regex(#"^Files\[((?'name'(.*?))\[(?'length'(\d+))\],?)*\]$");
var input = "Files[file1.jpg[2066654],file2.png[234235],file3.gif[56476788]]";
var match = regex.Match(input);
var names = match.Groups["name"].Captures.Cast<Capture>();
var lengths = match.Groups["length"].Captures.Cast<Capture>();
var output =
names
.Zip(lengths, (f, n) => new
{
file = f.Value,
length = int.Parse(n.Value)
})
.ToArray();
That gives me:
file
length
file1.jpg
2066654
file2.png
234235
file3.gif
56476788
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'
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).
I am trying to convert my search functionality to allow for fuzzy searches involving multiple words. My existing search code looks like:
// Split the search into seperate queries per word, and combine them into one major query
var finalQuery = new BooleanQuery();
string[] terms = searchString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
foreach (string term in terms)
{
// Setup the fields to search
string[] searchfields = new string[]
{
// Various strings denoting the document fields available
};
var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, searchfields, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
finalQuery.Add(parser.Parse(term), BooleanClause.Occur.MUST);
}
// Perform the search
var directory = FSDirectory.Open(new DirectoryInfo(LuceneIndexBaseDirectory));
var searcher = new IndexSearcher(directory, true);
var hits = searcher.Search(finalQuery, MAX_RESULTS);
This works correctly, and if I have an entity with the name field of "My name is Andrew", and I perform a search for "Andrew Name", Lucene correctly finds the correct document. Now I want to enable fuzzy searching, so that "Anderw Name" is found correctly. I changed my method to use the following code:
const int MAX_RESULTS = 10000;
const float MIN_SIMILARITY = 0.5f;
const int PREFIX_LENGTH = 3;
if (string.IsNullOrWhiteSpace(searchString))
throw new ArgumentException("Provided search string is empty");
// Split the search into seperate queries per word, and combine them into one major query
var finalQuery = new BooleanQuery();
string[] terms = searchString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
foreach (string term in terms)
{
// Setup the fields to search
string[] searchfields = new string[]
{
// Strings denoting document field names here
};
// Create a subquery where the term must match at least one of the fields
var subquery = new BooleanQuery();
foreach (string field in searchfields)
{
var queryTerm = new Term(field, term);
var fuzzyQuery = new FuzzyQuery(queryTerm, MIN_SIMILARITY, PREFIX_LENGTH);
subquery.Add(fuzzyQuery, BooleanClause.Occur.SHOULD);
}
// Add the subquery to the final query, but make at least one subquery match must be found
finalQuery.Add(subquery, BooleanClause.Occur.MUST);
}
// Perform the search
var directory = FSDirectory.Open(new DirectoryInfo(LuceneIndexBaseDirectory));
var searcher = new IndexSearcher(directory, true);
var hits = searcher.Search(finalQuery, MAX_RESULTS);
Unfortunately, with this code if I submit the search query "Andrew Name" (same as before) I get zero results back.
The core idea is that all terms must be found in at least one document field, but each term can reside in different fields. Does anyone have any idea why my rewritten query fails?
Final Edit: Ok it turns out I was over complicating this by a LOT, and there was no need to change from my first approach. After reverting back to the first code snippet, I enabled fuzzy searching by changing
finalQuery.Add(parser.Parse(term), BooleanClause.Occur.MUST);
to
finalQuery.Add(parser.Parse(term.Replace("~", "") + "~"), BooleanClause.Occur.MUST);
Your code works for me if I rewrite the searchString to lower-case. I'm assuming that you're using the StandardAnalyzer when indexing, and it will generate lower-case terms.
You need to 1) pass your tokens through the same analyzer (to enable identical processing), 2) apply the same logic as the analyzer or 3) use an analyzer which matches the processing you do (WhitespaceAnalyzer).
You want this line:
var queryTerm = new Term(term);
to look like this:
var queryTerm = new Term(field, term);
Right now you're searching field term (which probably doesn't exist) for the empty string (which will never be found).
I'm trying to get the 'normal' url for a users default calendar feed (e.g. http://www.google.com/calendar/feeds/jo#gmail.com/private/full). I would like to use the jo#gmail.com part of the URL as a unique ID for that calendar.
I know I can do things with the default calendar using the URL http://www.google.com/calendar/feeds/default/private/full. However, I can't find a way to construct a CalendarEntry from that URL (I could then try SelfUri and some other properties to see if the 'normal' url is in there somewhere), or to convert it to the 'normal' url in any way.
And I know I can get the list of Calendars like this:
CalendarQuery query_cal = new CalendarQuery();
query_cal.Uri = new Uri( "http://www.google.com/calendar/feeds/default/allcalendars/full" );
CalendarFeed resultFeed = (CalendarFeed) service.Query( query_cal );
foreach ( CalendarEntry entry in resultFeed.Entries )
{ ... }
However, I can't find any way to know which of those entries matches the default calendar.
Or any other way to get that normal url for the default calendar.
It's probably not the best method, but I use this and it works:
feedstring = resultfeed.Entries.Item(calendarIndex).Id.AbsoluteUri.Substring(63)
postUristring = "https://www.google.com/calendar/feeds/" & feedstring & "/private/full"
Dim postUri As New Uri(postUristring)
Just use calendarIndex = 0 for the default calendar. Shouldn't be too hard to convert to C#!
Thank you SO much! That works perfectly! Here is my final code:
CalendarQuery query = new CalendarQuery();
query.Uri = new Uri("https://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarFeed resultFeed = (CalendarFeed)service.Query(query);
int calendarIndex = 0;
string postUristring = string.Empty;
foreach (CalendarEntry entry2 in resultFeed.Entries)
{
if (entry2.Title.Text == "My Pregnancy Calendar")
{
string feedstring = resultFeed.Entries[calendarIndex].Id.AbsoluteUri.Substring(63);
postUristring = "https://www.google.com/calendar/feeds/" + feedstring + "/private/full";
}
calendarIndex++;
}