Regular Expression MatchCollection, OfType and Linq

by Janus Knudsen 5. February 2010 00:06

When I work with Regular Expression and the MatchCollection –> Match, I often find myself struggling with tedious repetitive and trivial approaches, foreach match get groups etc. etc., Sometimes I even forget how the MatchCollection and Match objects works :$

However the MatchCollection class stores a list of successful matches found by applying the regular expression pattern to an input string. And each of those matches can be accessed through the Match object.

Example:

IP addresses: (referred as ipText)
123.54.63.0
255.257.0.1  -> This one has an illegal number
0.255.255.12
192.168.1.1

 

Regular Expression to match each octet:

Regex regex = new Regex(@"(?<First>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Second>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Third>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Fourth>2[0-4]\d|25[0-5]|[01]?\d\d?)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace)

MatchCollection matches = regex.Matches(ipText);
ArrayList fooCollection; //old school to show the difference ;)
foreach (Match match in matches) 
{ 
Foo foo = new Foo(); 
if (match.Groups[“First”].Value == "192") 
	{ 
	//something to do... maybe create an object to store result in 
	foo.FirstOctet = match.Groups[“First”].Value; 
	foo.SecondOctet = match.Groups[“Second”].Value; 
	.... 
	FooCollection.Add(foo); 
	} 
 }

You can probably see how tedious and time consuming this is?

Instead we should use the new OfType and Linq, OfType filters the underlying elements by the specified type:

var matches = regex.Matches(sb.ToString()).OfType<MatchCollection>();

No we can have some fun with our precious Linq

matches.Select....

But we can go even further…. I’ve created a small extension for use with the Regex class, like this:

public static class Extension 
{ 
	public static IEnumerable<Match> FindMatches(this Regex regex, string value) 
	{ 
		foreach (var m in regex.Matches(value).OfType<MatchCollection>().OfType<Match>()) 
			yield return m; 

	} 

}

And now we can populate our Foo as we did earlier:

Regex regex = new Regex(@"(?<First>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Second>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Third>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Fourth>2[0-4]\d|25[0-5]|[01]?\d\d?)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); 

IEnumerable<Foo> foos = from p in regex.FindMatches(ipText) 
				where p.Groups["First"].Value == "192" 
				select new Foo() 
				{ 
					FirstOctet = p.Groups["First"].Value, 
					SecondOctet = p.Groups["Second"].Value
				...
				};

How easy was that? [:)] 

Tags: ,

Welcome to BlogEngine.NET 1.6.0

by Administrator 24. January 2010 00:00

If you see this post it means that BlogEngine.NET 1.6.0 is running and the hard part of creating your own blog is done. There is only a few things left to do.

Write Permissions

To be able to log in to the blog and writing posts, you need to enable write permissions on the App_Data folder. If you’re blog is hosted at a hosting provider, you can either log into your account’s admin page or call the support. You need write permissions on the App_Data folder because all posts, comments, and blog attachments are saved as XML files and placed in the App_Data folder. 

If you wish to use a database to to store your blog data, we still encourage you to enable this write access for an images you may wish to store for your blog posts.  If you are interested in using Microsoft SQL Server, MySQL, VistaDB, or other databases, please see the BlogEngine wiki to get started.

Security

When you've got write permissions to the App_Data folder, you need to change the username and password. Find the sign-in link located either at the bottom or top of the page depending on your current theme and click it. Now enter "admin" in both the username and password fields and click the button. You will now see an admin menu appear. It has a link to the "Users" admin page. From there you can change the username and password.  Passwords are hashed by default so if you lose your password, please see the BlogEngine wiki for information on recovery.

Configuration and Profile

Now that you have your blog secured, take a look through the settings and give your new blog a title.  BlogEngine.NET 1.4 is set up to take full advantage of of many semantic formats and technologies such as FOAF, SIOC and APML. It means that the content stored in your BlogEngine.NET installation will be fully portable and auto-discoverable.  Be sure to fill in your author profile to take better advantage of this.

Themes and Widgets

One last thing to consider is customizing the look of your blog.  We have a few themes available right out of the box including two fully setup to use our new widget framework.  The widget framework allows drop and drag placement on your side bar as well as editing and configuration right in the widget while you are logged in.  Be sure to check out our home page for more theme choices and downloadable widgets to add to your blog.

On the web

You can find BlogEngine.NET on the official website. Here you'll find tutorials, documentation, tips and tricks and much more. The ongoing development of BlogEngine.NET can be followed at CodePlex where the daily builds will be published for anyone to download.

Good luck and happy writing.

The BlogEngine.NET team

Tags: ,

BlogEngine.NET

T-SQL Pivot String Concatenation uden XML

by Janus Knudsen 5. November 2009 16:03

En lidt utraditionel brug af ISNULL, men yderst brugbar når man lige står og skal samle værdier. Oftest gøres den slags i applikationslaget, men T-SQL kan nu også gøre det :)

f1 f2
1 a
1 b
2 f
2 g
2 k

Resultatet vi gerne vil have frem:

  • 1 a, b
  • 2 f, g, k

 

Lidt demodata:

create table CoaTest( 
	f1 varchar(25), 
	f2 varchar(25) 
)

insert into CoaTest values(1, 'a') 
insert into CoaTest values(1, 'b') 
insert into CoaTest values(2, 'f') 
insert into CoaTest values(2, 'g')
insert into CoaTest values(2, 'k')

Og så en funktion til at gøre arbejdet :)

create function fnConcatenate(@f Date)) 
returns varchar(50) 
as 
begin 
	declare @sql varchar(255) 

	select @sql = ISNULL(@sql, '') + f2 + ', ' from CoaTest
		where [f1] = @f  
	
	return @sql 

end 

Og et funktionskald:
  
select f1, MIN(dbo.fnConcatenate(f1)) from CoaTest
group by f1 


Det kan laves mere generisk, men er det nødvendigt? YAGNI :)

Tags:

Egen blog

by Janus Knudsen 20. October 2009 21:23

Så fik jeg endelig min egen blog, hosted hos www.yourhost.dk til 48kr om mdr, det er jo fundet til prisen.

- Jeg har tidligere haft blog hos dotnetforum.dk, men pga. ringe tilslutning valgte Guidmaster at lukke ned Yell lidt trist, men livet går jo nok videre.

Tags:

Exception Handling – Oh my God

by Administrator 30. April 2009 21:14

Det her er faktisk en gammel slager helt tilbage fra dengang hvor jeg var ny i branchen. Jeg kan huske at jeg altid gjorde meget ud af at håndtere exceptions(efter et par år hvor jeg ikke anede hvad jeg lavede *LOL*), error handling var underligt nok ret sjældent i regulær old-school ASP, men såsnart det stod på WinApplications udviklet i VB6 så var der ingen vej uden om, eller rettere det var ihvertfald det jeg begyndte at forstå.

Når alt kommer til at alt var det nu ikke så underligt, for det hele var stadig lidt nyt for alle og for at være dygtig; ja så skulle man da håndtere sine errors (det hed vidst heller ikke Exceptions dengang i VB6 Undecided ) . What a pain at skrive de samme catch-blokke om og om igen, men så pludselig dukkede der en ny sag op på gaden: VB Watch Profiler, Protector and Debugger, pludselig var det muligt at udvikle en mere struktureret error handling woohaa – det var sørme tider. Der gik desværre heller ikke lang tid førend vores kode var totalt bloated til med de “snedige” strukturerede templates som man blot kunne smide på alle sine funktioner ved at højreklikke og vælge “Apply Error Handling, template… “ Smart ik Cool

Jeg har lige smidt at par billeder ind af de gamle dage sår’n for at skabe lidt stemning:

Create Project:

vbcreateproejct

IDE:

vb

Jo hylme var det smart og ikke mindst nemt, det gjorde faktisk min tid som udvikler meget nemmere. Det var ihvertfald nemmere at få en Windows Applikation til at køre uden synlige fejl! Nu skal det jo heller ikke lyde som om alt lykke blot var gjort, vi havde da naturligvis smidt lidt håndtering ind på udvalgte steder og derved kunne fortsætte gracefully med execution – bare rolig Smile

Men nu her det sidste lange stykke tid er man også begyndt med smarte Exception Policies Frameworks, hvilket egentlig er rigtigt gode sålænge de er brugt på den rigtige måde. Problemet er bare at der går virkelig lang tid imellem “den rigtige måde” (IMHO Innocent)

Desværre hænger meget af denne overdone/ overgjorte måde nok sammen med Microsoft Enterprise Library med Exception Policy og Logging. Nu er man begyndt at logge exceptions i alle lag, og for at gøre det kræves der så en try-catch-finally, den krydres man så med lidt Logging i catch og oftest en rethrow. Aha.. men hvad er det så lige man gør udover at logge fejlen, smide fejlen videre? Ja.. og igen findes der mange eksempler på en

try { }

catch (Exception e)
{

//do some logging;

throw e;

}

Kan det blive mere forunderligt? En logging i metoden og bagefter ødelægger vi lige call-stacken med vores skønne e, ja vi ser jo også eksempler på nogle som prøver at forfine det.. for jo jo, vi kan skam også skrive vores egne messages :

   1: try-catch (Exception e)
   2:  {
   3: //do some logging; 
   4: throw new Exception(“Something went wrong….” + e.Message);
   5: } 

Homefree… nu har vi da selv skrevet noget og læner os veltilfredse tilbage hmmm  NOT!!!

Exception klassen er ikke beregnet til den slags, hvis man endelig skal gøre det så må man igang med custom exceptions og overveje strategien og budskabet man ønsker at kommunikere ud.

Anyway – custom exceptions er en helt anden boldbane end den jeg skriver om her, lad os holde os til Exception Handling.

Problemet er den unødige logging i metoden og som man så bagefter smider videre til næste metode som så igen gør det samme osv osv. Hver metodes catch logger til en exception-log af en art, totalt information-overflow. Ikke nok med information-overflow, vi kommer også til at skrive alt for meget unødig kode.

En fornuftig Exception Handling ville derimod kunne opnåes meget nemmere, blot undlade catch-blokke medmindre man rent faktisk har en mening med at håndtere fejlen – det kunne være catch db-timeout –> raise event to user –> retrying database… eller ligeledes med file write/ read , altså i tilfælde hvor man er afhængig af eksterne resources.

Undlade Exception Handling? Hvad snakker manden om? Ja, undlade siger jeg Tongue out, blot lade være med at skrive noget ExceptionHandling kode førend vi rent faktisk er oppe på brugerlevel. I WebApplicationen/ Metoden i code-behind, fault i web/ wcf service, lige på det niveau.. her skal vi logge fejlen og tolke hvad den betyder, oversætte den til noget forståeligt og bagefter præsentere brugeren for en kort og venlig information om noget der er gået rask-ruskeme helt galt!

Ja og faktisk ikke engang her behøver man catch-blokke, man kunne eks.vis bruge ELMAH og så styre sine exception handling og logging igennem modules.

Well.. jeg kan se et enkelt tilfælde hvor man bør håndtere sin exception (udover de eksterne resources), lad os sige vi skal skrive noget til databasen igennem et ajax-kald –> WCF-service, og vi gerne vil informere brugeren om det er gået godt eller skidt. Her vil vi typisk håndtere fejlen i WCF, pakke den ind i et fault-object og smide ud til clienten igen og så præsentere det på en pæn måde vha. noget JavaScript oa.

 

Men hvor ellers?

Tags:

Nyt Job

by Janus Knudsen 13. April 2009 21:14

Sådan… nu blev det lidt mere officielt her efter 3 måneders ansættelse i Alpha Solutions a/s. Jeg var så heldig at komme til jobsamtale i november 2008 og efter nogle meget positive møder fandt vi ud af der var noget at bygge videre på. Jeg kom ind i Alphateamet d. 5. januar 2009 hvilket jeg er ekstremt glad for.

Jeg arbejder stadig med databaser, dog ikke så meget som hos Infare Solutions a/s som jeg sagde farvel til d. 30. juni 2008 efter 8 års ansættelse. Det var ikke uden grund jeg var der i 8 år, men 8 år er lang tid og det var på tide at komme videre i min karriere. Istedet for mucho store databaser og millioner af transactioner i timen har jeg istedet fået en længe ønsket kundekontakt, projektplanlægning og mere .NET arkitektur ind i min dagligdag, specielt kundekontakten og planlægning er 2 vigtige begreber for mig.

Jeg har fået nogle rigtigt gode kollegaer, god ledelse og ikke mindst nogle rigtigt gode arbejdsforhold.

Tags:

Dependency Injection med StructureMap, part 1

by Administrator 31. March 2009 21:14

Jeg har tidligere haft interesse i at decouple systemer og assemblies, dels for at opnå en mere modulær opbygning, og nu samtidigt er det jo snart blevet total hype pga. TDD, unittesting og mocks. Jeg har tidligere studeret lidt [EBP], det er virkelig genialt - ingen tvivl om det, men også lidt omstændigt lige at udvikle til brug for en webapplication eller mindre Winapplication.

Så det var på tide jeg satte mig lidt ind i DI (Dependency Injection). DI består kort fortalt i at undgå at instanciere classer i sine classer, i det øjeblik man gør det vil man skabe dependencies som ikke nemt lader sig udskifte. Derudover gør det også testing/ mocking til et sandt helvede. Jeg har kigget lidt rundt på forskellige DI-framework; Spring.NET, Autofac, Ninject, Castle Windsor og StructureMap.

Måden man undgår at skabe en unødig binding imellem sine klasser og assemblies er som sagt vha. Dependency Injection, DI handler om at man skaber eller wirer forbindelser imellem klasser et eksternt sted fra evt. igennem XML-configuration eller Fluent-programming, det forklarer jeg om senere.

Med unødig binding/ high coupling som man ofte ser i kode: (pyt med at eksemplet er lidt trivielt og besynderligt med den average, i gamle dage krævede det et loop, dividende og check for at der var personer i collectionen – tider jeg husker, men ikke ligefrem savner [:D] )

WrongBinding har en stærk binding til Personklassen igennem instancieringen i linje 7.

public class WrongBinding
{
    IList persons;

    public WrongBinding()
    {
        persons = new Person().GetSomePersons();
    }

    public void CalculateAverageHeight()
    {
        decimal averageHeight;

        if (persons.Count > 0)
            averageHeight = persons.Average(x => x.Height);
    }
}

public class Person
{
    public int Height { get; private set; }
    public string Name { get; private set; }

    public List GetSomePersons()
    {
        return new List()
              {
                 new Person{Height = 185, Name = "Jan Gintberg"},
                 new Person{Height = 178, Name = "Nicolaj Kopernikus"},
                 new Person{Height = 180, Name = "Thomas Bo Larsen"}
             };
    }
}

 

Jeg vil næsten vove den påstand at ser man sådan noget kode bør der overvejes en refactoring, medmindre projektet er så lille og begrænset at det nærmest blot er en mock-up/ prototype/ demo i sig selv for at belyse og analysere problemområder under projektet. Nu skal jeg ikke gøre mig mere hellig end hvad godt er, tag et kig på den kode jeg skrev for ½år siden, jojo.. jeg kan skam også kode med stærk kobling *LOL*. Jeg vil dog vove den påstand at jeg er kommet lidt videre henimod noget der ligner noget loose-coupling ;)

 

Som et lille tip har jeg udviklet en extension til IEnumerable, på den måde undgår man helt de trivielle check:

public static class JKExtensions
{
    public static decimal? AverageOrNull(this IEnumerable type, Func selector)
    {
        try
        {
            return type.Average(selector);
        }
        catch (InvalidOperationException)
        {
            return null;
        }
    }
}

På den måde kan man blot kalde Average sådan her:

var averageHeight = persons.AverageOrNull(x => x.Height);

Vupti.. ingen redundant if-then opslidende tastearbejde – Remember DRY ?

Well, tilbage til emnet….

Det første jeg bemærkede ved Spring.NET var at alt konfiguration skulle skrives i XML, nu er jeg sådan med tiden blevet mere og mere modstander af XML. Til at starte med var det jo supersmart og totalt hipt, meeeenn…. ligefrem XML-programmering er lige at strække formattet lidt for langt IMHO(another post).
Spring.NET droppede jeg rimeligt hurtigt igen. Det skal dog lige nævnes at Spring.NET er meget andet end blot DI, hvilket jo naturligvis også skal tages med i overvejelserne, men nu var jeg kun på udkig efter et lightweight og decideret DI-framework.

Så kiggede jeg på Castle Windsor, her stødte jeg på et begreb kaldet Fluent Interface , Castle Windsor så rigtigt interessant ud og havde det ikke været for min lidt rebelske attitude så…. Nu var min nysgerrighed vakt og jeg har altid haft det sådan, at selvom det ligger i toppen af Googlesøgningen behøver det jo ikke være det eneste og bedste.

Jeg fandt 2 websider som har gennemgået de forskellige frameworks rimeligt grundigt, http://blog.ashmind.com/index.php/2008/08/19/comparing-net-di-ioc-frameworks-part-1/ og http://www.codinginstinct.com/2008/04/ioc-container-benchmark-unity-windsor.html 

Efter at have gennemlæst begge posts grundigt gik jeg videre med Autofac, lille og lækkert DI-framework. Jeg bankede en hurtig test sammen, men jeg fik en fornemmelse af at det ikke var helt gennemarbejdet, jeg kan dog sagtens tage fejl – så undersøg det selv :)

Så videre til Ninject og her må jeg nok sige, der for alvor fik åbnet mine øjne for DI. Ninject har en rigtigt interessant Dojo som beskriver DI på en nem og forståelig måde, her er god mulighed til at blive bekendt med hvad man bør forlange/ forvente af et DI-framework. Jeg fik dog aldrig kodet noget med Ninject, jeg ved ikke – syntes vidst der var lidt forvirring om performance hos http://www.codinginstinct.com/2008/04/ioc-container-benchmark-unity-windsor.html .. men pludselig sad jeg med StructureMap.

Jeg fortsætter med part 2 i den kommende tid, så stay tuned :)

Tags:

About the author

Pic of myself :) Some kinda MCP and MCTS BI

ehh.... what's up Doc?

View Janus C. H. Knudsen's profile on LinkedIn

 

Page List