Mais uma vez, parse.

Ontem voltei à minha velha mania de Programador… O Rogério (http://liveservices.spaces.live.com/) me perguntou se eu conseguiria transformar um arquivo texto de informações exportadas do Active Directory em um arquivo CSV convencional com os valores…

O conteúdo do arquivo era mais ou menos similar ao que está abaixo:


dn; CN=antonio.silva,OU=Ativos,DC=cwbdis,DC=meudominio,DC=com
changetype; add
cn; antonio.silva
displayName; Antonio Silva

dn; CN=jose.Bicudo,OU=Ativos,DC=cwbdis,DC=meudominio,DC=com
changetype; add
cn; jose.Bicudo
displayName; Jose Bicudo

dn; CN=joao.junior,OU=Ativos,DC=cwbdis,DC=meudominio,DC=com
changetype; add
cn; joao.junior
displayName; João  Junior

dn; CN=joaquim.abravanel,OU=Ativos,DC=cwbdis,DC=meudominio,DC=com
changetype; add
cn; joaquim.abravanel
displayName;; QWRlbWFyIEpvc8OpIEJhcmFsZGk=


 

Qual o resultado esperado do processamento?

Gerar um arquivo nesse formato:


cn;displayname
antonio.silva;Antonio Silva
jose.Bicudo;Jose Bicudo
joao.junior;Jo
joaquim.abravanel;QWRlbWFyIEpvc8OpIEJhcmFsZGk=


Como processar um arquivo GRANDE?

(uma exportação de usuários do Active Directory razoável com ~60000 entidades (usuários) tem a ordem de 8MB de conteúdo.

Simples : Parse com Regular Expression.

 

    internal static class Parse

    {

        public static IDictionary<string, string> ObterRegistros(string strContents)

        {

            Regex rgCN = new Regex(@"(?<CN>cn;s)(?<name>w+.w+)|(?<CN>cn;;s)(?<name>w*.w*)|(?<CN>cn;s)(?<name>w+)",

    RegexOptions.IgnoreCase

    | RegexOptions.Multiline

    | RegexOptions.IgnorePatternWhitespace

    | RegexOptions.Compiled

    );

            Regex rgdisplayname = new Regex(@"(?<lixo>(?<display>displayName;;s)(?<fullname>w*W*))|(?<display>displayName;s)(?<fullname>(?<name>w*s*’*)+)|(?<display>displayName;s)(?<fullname>(?<name>w*W*s*)*)|(?<display>displayName;s)(?<fullname>(?<name>w*W*s*.*)*)",

    RegexOptions.IgnoreCase

    | RegexOptions.Multiline

    | RegexOptions.IgnorePatternWhitespace

    | RegexOptions.Compiled

    );

            Dictionary<string, string> lista = new Dictionary<string, string>();

            MatchCollection cns = rgCN.Matches(strContents);

            MatchCollection displays = rgdisplayname.Matches(strContents);

            try

            {

                for (int i = 0; i < cns.Count; i++)

                {

                    if (!lista.ContainsKey(cns[i].Groups["name"].Value))

                    {

                        lista.Add(cns[i].Groups["name"].Value, displays[i].Groups["fullname"].Value.Replace(@"

dn", string.Empty).Replace(@"

", string.Empty));

                    }

                }

            }

            catch (Exception)

            {

                //throw;

            }

            return lista;

        }

    }

 

Olha só que moleza o exemplo de chamada:

 

 

        Dictionary<string, string> pares;

        private void button1_Click(object sender, EventArgs e)

        {

            OpenFileDialog ofd = new OpenFileDialog();

            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)

            {

                Application.DoEvents();

                string texto = System.IO.File.ReadAllText(ofd.FileName);//isso vai demorar um pouco

                pares = (Dictionary<string,string>)Parse.ObterRegistros(texto);

                StringBuilder sb = new StringBuilder();

                sb.AppendLine("cn;displayname");

                foreach (KeyValuePair<string,string> obj in pares)

                {

                    sb.AppendFormat("{0};{1}", obj.Key, obj.Value);

                    sb.AppendLine();

                }

 

                System.IO.File.WriteAllText(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "exportresult.csv"), sb.ToString());

                MessageBox.Show(string.Format("Arquivo salvo em {0}", System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "exportresult.csv")));

            }

        }

 

viu como é simpes?