Avatar billede nat Nybegynder
21. oktober 2005 - 11:31 Der er 39 kommentarer og
1 løsning

Regex der ikke dur

Jeg har fået følgende:

return Regex.IsMatch(s, @"^\"[^\"]*\"$");

Men, jeg får en fejl når @ står der, og hvis jeg sletter den, virker det ikke - dvs. at den finder ikke noget tekst i "" og gør så ikke det efterfølgende den skal.

Så, hvordan laver jeg en regex der fanger tekst der står i "" som f.eks.: "Hej med dig, her står noget tekst i gåseøjne"
Avatar billede arne_v Ekspert
21. oktober 2005 - 11:36 #1
det er vist min fejl

:-)

prøv:

return Regex.IsMatch(s, "^\\\"[^\\\"]*\\\"$");
Avatar billede khs1a Nybegynder
21. oktober 2005 - 11:39 #2
i vb ville man skrive stringen således "^\""[^\""]*\""$"
mon ikke det er det samme i C#
Avatar billede arne_v Ekspert
21. oktober 2005 - 11:48 #3
C# er lidt anderledes
Avatar billede arne_v Ekspert
21. oktober 2005 - 11:49 #4
husk og fjern ^ og $ hvis xx"xx"xx også skal matche og ikke kun "xx"
Avatar billede nat Nybegynder
21. oktober 2005 - 13:53 #5
hmm når jeg tjekker på sb.ToString() ( bool text = IsText(sb.ToString());) siger den bare at text er false - og jeg ved at der er tekst der står i "". Tjekker jeg på noget forkert?

(Koden kan findes her: http://exp.dk/spm/657746)
Avatar billede nat Nybegynder
21. oktober 2005 - 14:00 #6
Jeg har nu prøvet at sætte den ind i foreach, og har her defineret følgende:

bool text = IsText(dr[dc].ToString());
if(text)
{
gør noget her
}

Men text er stadigvæk false, selv om den lige har lavet en stregn i "".
Avatar billede arne_v Ekspert
21. oktober 2005 - 14:07 #7
prøv lige og kør det her eksempel:

using System;
using System.Text.RegularExpressions;

namespace E
{
    public class Tester
    {
        public static bool IsText(string s)
        {
            return Regex.IsMatch(s, "^\\\"[^\\\"]*\\\"$");
        }
        public static bool ContainsText(string s)
        {
            return Regex.IsMatch(s, "\\\"[^\\\"]*\\\"");
        }
    }
    public class MainClass
    {
        public static void Test(string s)
        {
            Console.WriteLine(s + " IsText : " + Tester.IsText(s));
            Console.WriteLine(s + " ContainsText : " + Tester.ContainsText(s));
        }
        public static void Main(string[] args)
        {
            Test("abc");
            Test("\"abc\"");
            Test("a\"b\"c");
        }
    }
}
Avatar billede nat Nybegynder
21. oktober 2005 - 14:16 #8
mærkeligt - kan jo godt se at den regex du har sendt mig passer.... Men hvorfor får jeg ikke fat i mine "" i min tekst. Tjekker jeg på det forkerte når jeg vælger at sige at bool text = IsText(dr[dc].ToString());
Avatar billede arne_v Ekspert
21. oktober 2005 - 14:18 #9
Hvad indeholder dr[dc].ToString() ?
Avatar billede nat Nybegynder
21. oktober 2005 - 14:50 #10
Tekst, f.eks.: "Hej med dig"
Avatar billede arne_v Ekspert
21. oktober 2005 - 14:52 #11
Og double quotene er der faktisk i teksten ?
Avatar billede nat Nybegynder
21. oktober 2005 - 14:52 #12
Jeg har prøvet nu med sb.ToString, og brugt metoden
public static bool ContainsText(string s)
        {
            return Regex.IsMatch(s, "\\\"[^\\\"]*\\\"");
        }
Og nu kan den godt umiddelbart godt finde tekst der er inde i " ". Je gskal lige se hele filen når den er færdig...
Avatar billede nat Nybegynder
21. oktober 2005 - 15:04 #13
Ja begge "" er der, når jeg laver en quick watch på dr[dc]
Avatar billede nat Nybegynder
21. oktober 2005 - 15:19 #14
Hmmm, den får godt nok fundet de tekster der er " ", men den fjerner også \n (jeg erstatter \n med \ ) udenfor "", den skal kunne fjerne dem der forekommer indenfor gåseøjne: eks. taget fra filen:

"";"20050413101000";"";"";"";"";"";""\137;
Avatar billede nat Nybegynder
21. oktober 2005 - 15:20 #15
dvs. den \ der er før 137; skal ikke være der!
Avatar billede arne_v Ekspert
21. oktober 2005 - 15:27 #16
ContainsText fjerner ingenting

hvordan ser den kode som fjerner noget ud ?
Avatar billede nat Nybegynder
21. oktober 2005 - 15:42 #17
Nej nej, det var dårligt formuleret, men den fanger noget tekst der står i " " og af en eller anden grund får den så også fat på det der står efter "" (rigtigt forstået?). Når  ContainsText er true, skal den fjerne linie skift, dette gør jeg således:

bool text = MatchRegex.IsText(sb.ToString());
if(text)
{
//Fjerne "tvunget" linjeskif
sb.Replace("<br>","\\");
//Udkift linkeskift med en tegnkombination \
sb.Replace("\n", "\\");
sb.Replace("\r\n", "\\");
}
Avatar billede arne_v Ekspert
21. oktober 2005 - 20:16 #18
du vil have begrænset din replace til kun at virke mellem "" ?
Avatar billede arne_v Ekspert
21. oktober 2005 - 20:29 #19
using System;
using System.Text;

namespace E
{
    class MainClass
    {
        public static string XReplace(string s, char fnd, char rpl)
        {
            StringBuilder sb = new StringBuilder();
            bool inq = false;
            for(int i = 0; i < s.Length; i++)
            {
                if(s[i] == '"')
                {
                    inq = !inq;
                }
                if(s[i] == fnd && inq)
                {
                    sb.Append(rpl);
                }
                else
                {
                    sb.Append(s[i]);
                }
            }
            return sb.ToString();
        }
        public static void Main(string[] args)
        {
            string s = "\"a\"\n\"b\nb\"";
            Console.WriteLine(s);
            Console.WriteLine(s.Replace('\n', '#'));
            Console.WriteLine(XReplace(s, '\n', '#'));
        }
    }
}
Avatar billede nat Nybegynder
27. oktober 2005 - 09:17 #20
Ja, det er kun mellem "" jeg vil replace....

Kan jeg få dig til at tilpasse ovenstående kode til denne?

public void Iterate(object obj, out string position)
{
DataRow dr=(DataRow)obj;
           
           
            foreach (DataColumn dc in dr.Table.Columns)
            {
                bool needtoquote = !MatchRegex.IsNumber(dr[dc].ToString());
                bool date = MatchRegex.IsDate(dr[dc].ToString());
               
                if(needtoquote)
                {
                    sb.Append("\"");
                }
                if(date)
                {
                    sb.Append(DateTime.ParseExact(dr[dc].ToString(), "dd-MM-yyyy HH:mm:ss", new CultureInfo("en-US", false),  DateTimeStyles.AllowWhiteSpaces).ToString("yyyyMMddHHmmss"));
                }
                else
                {
                    sb.Append(dr[dc]);
                }
                if(needtoquote)
                {
                    sb.Append("\"");
                }
               
               
                sb.Append(";");
            }

            sb.Remove(sb.Length-1, 1);
            sb.Append("\n");
           
            bool text = MatchRegex.IsText(sb.ToString());
            if(text)
            {
                //Fjerne "tvunget" linjeskift
                sb.Replace("<br>","\\");
                //Udkift linkeskift med en tegnkombination
                sb.Replace("\n", "\\");
                //slet carriage return \r
               
               
            }
public class MatchRegex
    {
        public static bool IsNumber(string s)
        {
            return Regex.IsMatch(s, "^[0-9]+$");
        }
        public static bool IsDate(string s)
        {
            return Regex.IsMatch(s, "^[0-9]{2}-[0-9]{2}-[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}$");
        }
        public static bool IsText(string s)
        {
            return Regex.IsMatch(s, "\\\"[^\\\"]*\\\"");
        }
    }
  position="0";
}
Det vil bare være helt kanon :)
Avatar billede nat Nybegynder
27. oktober 2005 - 16:29 #21
Er det rigtigt hvis jeg bruger den således: XReplace(sb.ToString(), '\n', '\\');

Jeg har sat den ind efter sb.Remove(sb.Length-1, 1); sb.Append("\n"); (dem der er efter foreach).

Men det tager 100 år for den at skrive filen.......
Avatar billede arne_v Ekspert
27. oktober 2005 - 17:04 #22
det ser umiddelbart rigtigt ud

hvor stor er filen og hvor lang tid tager det ?
Avatar billede nat Nybegynder
27. oktober 2005 - 17:30 #23
Den er pt. 3,95 MB (men den bliver større efterhånden som der kommer flere og flere data i databasen, og det gør der).

Indtil videre har det taget 30 minutter og den er endnu ikke færdig. Før jeg ville fjerne \n tog det under et minut at generere filen...
Avatar billede nat Nybegynder
28. oktober 2005 - 10:21 #24
Det tog 1½ time, og da jeg kiggede i filen, var ingen af \n blevet erstattet med \. Så kan det passe at det er det rigtige jeg gør når jeg har skrevet XReplace(sb.ToString(), '\n', '\\');

Er det sb det skal sættes som strengen? Eller er det fordi at det er den forkerte sted jeg sætter det ind (efter foreach)?
Avatar billede arne_v Ekspert
28. oktober 2005 - 10:45 #25
har du husket at det er

noget = XReplace(sb.ToString(), '\n', '\\');

ikke bare

XReplace(sb.ToString(), '\n', '\\');
Avatar billede nat Nybegynder
28. oktober 2005 - 10:56 #26
Nej :(

Hvad skal det "noget" være?

DataRow dr=(DataRow)obj;

            foreach (DataColumn dc in dr.Table.Columns)
            {
                bool needtoquote = !MatchRegex.IsNumber(dr[dc].ToString());
                bool date = MatchRegex.IsDate(dr[dc].ToString());
               
                if(needtoquote)
                {
                    sb.Append("\"");
                }
                if(date)
                {
                    sb.Append(DateTime.ParseExact(dr[dc].ToString(), "dd-MM-yyyy HH:mm:ss", new CultureInfo("en-US", false),  DateTimeStyles.AllowWhiteSpaces).ToString("yyyyMMddHHmmss"));
                }
                else
                {
                    sb.Append(dr[dc]);
                }
                if(needtoquote)
                {
                    sb.Append("\"");
                }
                sb.Append(";");

               
            }

            sb.Remove(sb.Length-1, 1);
            sb.Append("\n");

            XReplace(sb.ToString(), '\n', '\\');
Avatar billede nat Nybegynder
28. oktober 2005 - 11:03 #27
f.eks. bare string tekst = XReplace(sb.ToString(), '\n', '\\'); ?
Avatar billede arne_v Ekspert
28. oktober 2005 - 11:17 #28
ja

hvor tekst så er det du bruger senere i koden
Avatar billede nat Nybegynder
28. oktober 2005 - 11:26 #29
i stedet for sb (f.eks. hvor jeg skriver sb.Append(dr[dc]); skriver jeg nu tekst.Append(dr[dc]); )
Avatar billede nat Nybegynder
28. oktober 2005 - 11:29 #30
Nææ det prøvede jeg lige, og en string har ikke append... Hvor er det så jeg skal bruge den? Eller skal jeg bare bruge noget andet end append?
Avatar billede arne_v Ekspert
28. oktober 2005 - 11:33 #31
hvor vil du lave den replace og hvad skal resultatet bruges til ?
Avatar billede nat Nybegynder
28. oktober 2005 - 11:41 #32
Jeg vil bruge den replace idet jeg skriver filen, før den bliver gemt. Det er det der sker i den kode jeg har vedhæftet. Replacen skal som skrevet kun ske i tekststrenge der er i "", og den tekst det drejer sig om ligger i sb (som har en append, hvor jeg kan tilføje ting til teksten). Teksten kommer fra en database og bliver skrevet til en tekstfil.

Evt. kan replacen ske efter at alle rækker i databasen er kørt igennem og ligger som tekst i sb. Hvilket var derfor at jeg ville gøre det efter foreach.

Jeg forstår ikke helt hvordan jeg skal bruge XReplace som du har givet mig....
Avatar billede nat Nybegynder
28. oktober 2005 - 13:59 #33
nu har jeg prøvet at bruge XReplace på følgende måde:

                        DataRow dr=(DataRow)obj;

            foreach (DataColumn dc in dr.Table.Columns)
            {
                bool needtoquote = !MatchRegex.IsNumber(dr[dc].ToString());
                bool date = MatchRegex.IsDate(dr[dc].ToString());
               
                string tekst = XReplace(dr[dc].ToString(), '\n', '#');

                if(needtoquote)
                {
                    sb.Append("\"");
                }
                if(date)
                {
                    //Test med datoformat
                    sb.Append(DateTime.ParseExact(dr[dc].ToString(), "dd-MM-yyyy HH:mm:ss", new CultureInfo("en-US", false),  DateTimeStyles.AllowWhiteSpaces).ToString("yyyyMMddHHmmss"));
                }
                else
                {
                    sb.Append(tekst);
                }
                if(needtoquote)
                {
                    sb.Append("\"");
                }
                sb.Append(";");
            }

            sb.Remove(sb.Length-1, 1);
            sb.Append("\n");

Men det er vist ikke rigtigt for den replacer ikke \n med \

Hvad gør jeg forkert?
Avatar billede arne_v Ekspert
28. oktober 2005 - 14:33 #34
jeg tror at du mener

                    DataRow dr=(DataRow)obj;

            foreach (DataColumn dc in dr.Table.Columns)
            {
                bool needtoquote = !MatchRegex.IsNumber(dr[dc].ToString());
                bool date = MatchRegex.IsDate(dr[dc].ToString());
             
                if(needtoquote)
                {
                    sb.Append("\"");
                }
                if(date)
                {
                    //Test med datoformat
                    sb.Append(DateTime.ParseExact(dr[dc].ToString(), "dd-MM-yyyy HH:mm:ss", new CultureInfo("en-US", false),  DateTimeStyles.AllowWhiteSpaces).ToString("yyyyMMddHHmmss"));
                }
                else
                {
                    sb.Append(dr[dc]);
                }
                if(needtoquote)
                {
                    sb.Append("\"");
                }
                sb.Append(";");
            }

            sb.Remove(sb.Length-1, 1);
            sb.Append("\n");
            string tekst = XReplace(sb.ToString(), '\n', '#');

og så udskriver du tekst
Avatar billede nat Nybegynder
31. oktober 2005 - 15:10 #35
jeg kan ikke få fat i 'tekst', da der hvor jeg udskriver tekst, ligger i en anden public metode... lige nu ser det således ud:

private StringBuilder sb=null;
public....
{
string filename=@"xxxxxxx.txt";
FileStream fs = File.Create(filename);
StreamWriter dinFil = new StreamWriter(fs, System.Text.Encoding.Default);
dinFil.Write(sb.ToString()); // her skal sb.ToString() vel erstattes med 'tekst'
dinFil.Close();
}
Avatar billede arne_v Ekspert
31. oktober 2005 - 19:54 #36
ja

men hvis du kan få fat i sb så kan du jo erstatte

string tekst = XReplace(sb.ToString(), '\n', '#');

med

sb = new StringBuilder(XReplace(sb.ToString(), '\n', '#'));
Avatar billede nat Nybegynder
02. november 2005 - 09:35 #37
Det gik straks meget bedre :D

Men nu få jeg så følgende som jeg ikke helt forstår hvorfor. Det ser ud til at den erstatter \n udenfor "".

Et udsnit af filen ser således ud nu:

"xx yy zz";"";0\20632;"nnmmm dddeee ddd";

Hvorfor kommer der \ imellem 0 og 20632 ?
Avatar billede nat Nybegynder
02. november 2005 - 09:40 #38
Ahh jeg har fundet ud af hvorfor. Det er et kommentar felt hvori jeg vil fjerne \n, og her har en skrevet "" inde i feltet, derfor brydes flowet med de rigtige "", så den skal vel faktisk tjekke på om "" er efterfult af et ; for at tekststrengen er slut, altså f.eks. "fgggd sss "her har brugeren skrevet noget i gåseøjne" fff sss";

Kan man det???
Avatar billede nat Nybegynder
03. november 2005 - 17:12 #39
Jeg fandt en løsning. Smider du ikke en svar arne_v :) Og en stor tak for hjælpen
Avatar billede arne_v Ekspert
03. november 2005 - 18:22 #40
ok
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester