2 matchcollections to 1 list - c#

Hi guys I have 2 MatchCollection:
MatchCollection users_ids = Regex.Matches(result, #"url"":""(.*?)""");
MatchCollection users_names = Regex.Matches(result, #"fullname"":""(.*?)""");
The number of mathces of 2 collections is equаl
I need to join all Matches to 1 List. Smth like this:
foreach (Match match in users_ids)
{
string id = match.Groups[1].Value.ToString();
// string name = users_names(every match) .Groups[1].Value.ToString();
online_list.Add(id + "|" + name);
}
Any solutions?=\

This looks like the perfect application of Zip, which goes through two enumerations, taking the item at the current index of each and mapping them into a result using the given function:
var matches = users_ids.Cast<Match>()
.Zip(users_names.Cast<Match>(),
(id, name) => id.Groups[1].Value + "|" + name.Groups[1].Value);

Related

C# Regex match case - split string and write to file output

Basically I have a text file of records in this format:
(1909, 'Ford', 'Model T'),
(1926, 'Chrysler', 'Imperial'),
(1948, 'Citroën', '2CV'),
That I want to output to a text file in the following format
new Vehicle() { Id = 1, Year = 1909, Make = "Ford", Model = "Model T" },
new Vehicle() { Id = 2, Year = 1926, Make = "Chrysler", Model = "Imperial" },
new Vehicle() { Id = 3, Year = 1948, Make = "Citroën", Model = "2CV" },
I know I need to split each line in to the relevant text sections, e.g. trying to follow something like this SO question. But have hit mental block on how to get the relevant matching string sections for Year, Make and Model.
So far I have found this, that finds everthing between the parentheses:
\(([^()]+)\)
But not sure how to then group the the values and split by the commas:
Any help greatly appreciated.
Regex to get them in groups:
\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*
Make note there is problem about Citroën => You have to enter all the special symbols not within a-z, A-Z (like ë ü ÿ etc..)
To use in code, You will get the groups 1st:
string cars = #"(1909, 'Ford', 'Model T'),"
string pattern = #"\((\d+),\s+[']([\w\së]+)['],\s+[']([\w\s]+)[']\)[,]*";
var lResult = Regex.Match(cars, pattern);
if(lResult.Success)
foreach( var iGroup in lResult.Groups)
Console.WriteLine(iGroup);
In lResult.Groups You got the info about car, You have just output it to the file as You need.
C# 6.0:
Console.WriteLine($"new Vehicle() {{ Id = 1, Year = {lResults.Groups[1]}, Make = \"{lResults.Groups[2]}\", Model = \"{lResults.Groups[3]}\"}},");
Old syntax:
Console.WriteLine(#"new Vehicle() { Id = 1, Year = "+ lMatch.Groups[1]+", Make = "+ lMatch.Groups[2] + ", Model = "+ lMatch.Groups[3] + " },");
Once You get this automatized into for loops, You can add Id easily.
My example have in Groups[0] whole string, so this is why my indexing starting from 1 to 3.
As #Toto said, \w already includes \d, there is no need to write it then.
Why not use string.Split(',')? Would be faster than Regex and suits for you (first delete the last ',' of each line, of course.
if you are willing to use a parser framework (which is maybe a little bit of an overkill), you could use for example sprache. Example without proper error handling:
Parser<string> stringContent =
from open in Parse.Char('\'').Once()
from content in Parse.CharExcept('\'').Many().Text()
from close in Parse.Char('\'').Once()
select content;
Parser<string> numberContent = Parse.Digit.AtLeastOnce().Text();
Parser<string> element = stringContent.XOr(numberContent);
Parser<List<string>> elements =
from e in element.DelimitedBy(Parse.Char(',').Token())
select e.ToList();
Parser<List<string>> parser =
from open in Parse.Char('(').Once()
from content in elements
from close in Parse.Char(')').Once()
select content;
var input = new List<string> { "(1909, 'Ford', 'Model T')", "(1926, 'Chrysler', 'Imperial')", "(1948, 'Citroën', '2CV')" };
foreach (var line in input)
{
var parsed = parser.Parse(line);
var year = Int32.Parse(parsed[0]);
var make = parsed[1];
var model = parsed[2];
Console.WriteLine(">> " + year + " " + make + " " + model);
}
You can use this snippet based on named capture groups:
var cars = new List<string>() {
"(1909, 'Ford', 'Model T')",
"(1926, 'Chrysler', 'Imperial')",
"(1948, 'Citroën', '2CV')",
};
var regex = #"(?<Year>\d+).*?'(?<Brand>.*?)'.*?'(?<Model>.*?)'";
foreach (var car in cars)
{
var match = Regex.Match(car, regex);
if (match.Success)
{
Console.WriteLine($"{match.Groups["Brand"]} make {match.Groups["Model"]} in {match.Groups["Year"]}");
}
}
Which will print:
Ford make Model T in 1909
Chrysler make Imperial in 1926
Citroën make 2CV in 1948

C# Format string in a way I can get different values from it

What is the best way to format the below string in a way so that I can separate out and find the value of PractitionerId, PhysicianNPI, PhysicianName etc.
"PractitionerId:4343343434 , PhysicianNPI: 43434343434, PhysicianName:
John, Doe, PhysicianPhone:2222222222 , PhysicianFax:3333333333 "
So finally I want something like this:
var practitionerId = "4343343434 ";
var physNPI = "43434343434";
var phyName = "John, Doe";
I was thinking of splitting with the names and finding the values assigned to each field but I am not sure if that is the best solution to it.
You could probably generalise this with a regular expression, then use it to build a dictionary/lookup of the terms.
So:
var input= "PractitionerId:4343343434 , PhysicianNPI: 43434343434,"
+ " PhysicianName: John, Doe, PhysicianPhone:2222222222 ,"
+ " PhysicianFax:3333333333";
var pattern = #"(?<=(?<n>\w+)\:)\s*(?<v>.*?)\s*((,\s*\w+\:)|$)";
var dic = Regex
.Matches(input, pattern)
.Cast<Match>()
.ToDictionary(m => m.Groups["n"].Value,
m => m.Groups["v"].Value);
So now you can:
var practitionerId = dic["PractitionerId"];
or
var physicianName = dic["PhysicianName"];
You could get the exact information, doing something like:
var str = "PractitionerId:4343343434 , PhysicianNPI: 43434343434, PhysicianName: John, Doe, PhysicianPhone:2222222222 , PhysicianFax:3333333333 ";
var newStr = str.Split(',');
var practitionerID = newStr[0].Split(':')[1]; // "4343343434"
var physicianNPI = newStr[1].Split(':')[1].Trim(); // "43434343434"
var phyName = newStr[2].Split(':')[1].Trim() + "," + newStr[3]; // "John, Doe"
There are cleaner solutions using Regex patterns though.
Also, you need to parse the corresponding variables to the specific data type you want. Everything here is being treated as a string
Since you seperate information with ",", this should work:
string[] information = yourWholeString.Split(",");
string practitionerId = information[0];
string physNPI = information[1];
string phyName = information[2] + information[3];

Linq to find match from three lits

I'm banging my head against the wall to try to figure something out. I've broken down what I'm trying to figure out in the simplest explanation as I can below:
Let's say I have these two string arrays with the following data:
string[] firstName = new string[2];
string[] lastName = new string[2];
firstName[0] = "John";
firstName[1] = "Jane";
lastName[0] = "Doe";
lastName[1] = "Doe";
I then have a method that this arrays are passed into:
private void Matches(IEnumerable<string> firstNames, IEnumerable<string> lastNames)
{
}
I then have two variables:
string myFirstName = "John";
string myLastName = "Doe";
How can I use Linq in the Matches method to find a complete match on the names being passed in? (the header of the Matches method has to remain how it is, unfortunately) Based on that data, I could I find the matches? I'm going gray trying to figure this one out....lol
Zip the two together and then just do a simple Where:
var myName = myFirstName + " " + myLastName;
firstNames.zip(lastNames, (first, last) => first + " " + last)
.Where(fullName=>fullName == myName)

How to get Last Index Of '\' or '//', whichever comes last?

I want to get lastindexof character from url which comes from the database on the basis of '\' or '//'
Say for example i have string like this
Administration\Masters\EmployeePulseDetailsMaster.aspx
Administration/Masters/SearchKnowYourCollegues.aspx
Administration//SMS//PushSMS.aspx
I am using that code
foreach (var item in SessionClass.UserDetails.SubModules)
{
if (Request.RawUrl.Contains(item.PageURL.Substring(item.PageURL.LastIndexOf('\\') + 1))
|| Request.RawUrl.Contains(item.PageURL.Substring(item.PageURL.LastIndexOf('/') + 1)))
{
Response.RedirectPermanent("~/Login.aspx");
}
}
You can use a regular expression to find the last occurrence of any character in a group by constructing a regular expression that looks like this:
[target-group][^target-group]*$
In your case, the target group is [/\\], so the search would look like this:
var match = Regex.Match(s, #"[/\\][^/\\]*$");
Here is a running example:
var data = new[] {
#"quick/brown/fox"
, #"jumps\over\the\lazy\dog"
, #"Administration\Masters\EmployeePulseDetailsMaster.aspx"
, #"Administration/Masters/SearchKnowYourCollegues.aspx"
, #"Administration//SMS//PushSMS.aspx"
};
foreach (var s in data) {
var m = Regex.Match(s, #"[/\\][^/\\]*$");
if (m.Success) {
Console.WriteLine(s.Substring(m.Index+1));
}
}
This prints
fox
dog
EmployeePulseDetailsMaster.aspx
SearchKnowYourCollegues.aspx
PushSMS.aspx
Demo.
I guess you want to determine if the name of the current page is in the list of SessionClass.UserDetails.SubModules. Then i'd use Request.Url.Segments.Last() to get only the name of the current page(f.e. PushSMS.aspx) and System.IO.Path.GetFileName to get the name of each url. GetFileName works with / or \:
string pageName = Request.Url.Segments.Last();
bool anyMatch = SessionClass.UserDetails.SubModules
.Any(module => pageName == System.IO.Path.GetFileName(module.PageURL));
if(anyMatch) Response.RedirectPermanent("~/Login.aspx");
You need to add using System.Linq; for Enumerable.Any.

Create String of Comma Separated Quotes from List

I have a class called user that contains a list of groups that are strings ( Group A, Group B, Group C)
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public User()
{
Groups = new List<string>();
}
}
I am then using a json deserializer to create the list of users and groups. However I would like to be able to get a string of the groups with this format for each user:
"Group A", "Group B", "Group C"
I have tried this:
string[] AllGroups;
AllGroups = (string[])usrList[0].Groups.ToArray();
return string.Join(",", AllGroups);
However it is giving me a list in this format (with no quotes):
Group A, Group B, Group C
Any idea what I am doing wrong here?
Any idea what I am doing wrong here?
Well you're not adding the quotes anywhere - so you're not getting them.
You can surround each item with quotes yourself easily enough:
return string.Join(", ", usrList[0].Groups.Select(x => "\"" + x + "\""));
That's assuming you're using .NET 4 or higher - if you're using .NET 3.5 (which doesn't have quite as good string.Join support) you need to create an array, but you don't need to cast it to string[] (as ToArray already returns an array)...
return string.Join(", ", usrList[0].Groups
.Select(x => "\"" + x + "\"")
.ToArray());
I've added a space after the comma delimiter as well, given your question - I suspect your current code is really giving you Group A,Group B,Group C.
Assuming you want to get "" as a result when there are no values, you can do this:
return "\"" + string.Join("\", \"", AllGroups) + "\"";
Note that this is not an empty string - it's a string which contains two quotes.
If you want to return null or the empty string using this code, you'd need to check the size of AllGroups first.
var AllGroups = usrList[0].Groups;
if (AllGroups.Count() == 0) return null;
else return "\"" + string.Join("\", \"", AllGroups) + "\"";

Categories