mboost-dp1

Search-replace C#


Gå til bund
Gravatar #51 - XorpiZ
20. maj 2010 11:06
Problemet er løst.

Det var ikke streamwriteren, der var problemet, det var denne stump kode, der gjorde det:

File.WriteAllText(filnavn, text); - den der skriver til filen 2. gang, efter der er kørt search/replace på den.

Da jeg tilføjede Encoding.UFT8 på denne, så kørte det som det skulle.

Tak for hjælpen (igen) :)
Gravatar #52 - XorpiZ
26. maj 2010 07:21
Så er jeg tilbage igen - denne gang med et nyt problem.

Jeg er ikke så logisk tænkende (mig og matematik er ikke de bedste venner), men jeg har følgende problem:

Jeg har en fil med en masse linjer i formatet
020000112345678ATU1242515   000000014252+00000000+ 


Der er ingen linjeskift af nogen art i filen, kun 2-4 mellemrum imellem første række tal og anden række tal - og så et + ELLER et - og 5-6 mellemrum efter anden række tal og frem til den næste række starter.

Jeg skal have følgende data hevet ud af filen:

Dataene efter "12345678" (Dvs. ATU1242515 og dataene efter de 2-4 mellemrum og hen til og med det første plus/minus).

Håber jeg har gjort mig forståelig, ellers er her lige et par eksempler:

0200000000320803312345678DE118045186   000000000021982+0000000000000000+ 

Skal returnere DE,118045186,000000000021982,+,

0200000000650803312345678DE146055147   000000000000592-0000000000000000+

Skal returnere DE,146055147,000000000000592,-,

Jeg er med på, at der skal laves en fa'ens masse string-manipulation, men jeg kan slet ikke lure, hvor jeg skal starte. Nogle ideer?
Gravatar #53 - mazing
26. maj 2010 11:14
Mit forsøg:

string crap = "020000112345678ATU1242515 000000014252+00000000+ 0200000000320803312345678DE118045186 000000000021982+0000000000000000+";

string[] uncleanedColl = crap.Split(new string[] {"12345678"}, StringSplitOptions.RemoveEmptyEntries);
foreach (string uncleaned in uncleanedColl)
{
// Find første + eller -
int endIndex = uncleaned.IndexOfAny(new char[] { '+', '-' });
if (endIndex <= 0)
{
// Huston we have a problem
continue;
}

// Find første mellemrum
int spaceIndex = uncleaned.IndexOf(' ');

// Opsplit "ATU1242515 000000014252+00000000+ 02000000003208033"
string code1 = uncleaned.Substring(0, spaceIndex); // ATU1242515
string code2 = uncleaned.Substring(spaceIndex, endIndex - spaceIndex).Trim(); // 000000014252
string sign = uncleaned.Substring(endIndex, 1); // +

// Hent bokstaver fra code1
string code0 = "";
for (int i = 0; i < code1.Length; i++)
{
if (char.IsLetter(code1, i))
code0 += code1[i];
else
break;
}

// Fjern bokstaver fra code1
code1 = code1.Substring(code0.Length);

System.Console.WriteLine("{0},{1},{2},{3},", code0, code1, code2, sign);

}

Output:

ATU,1242515,000000014252,+,
DE,118045186,000000000021982,+,


Hvis du har tænkt dig at bruge overstående, vil jeg anbefale at smide nogle ekstra checks ind :)
Gravatar #54 - XorpiZ
26. maj 2010 11:26
Det ser sgu udmærket ud, må jeg sige.

Jeg har i mellemtiden bikset noget slamkode sammen, der umiddelbart virker, men det er slet ikke så elegant som dit.

Mit er 100% afhængigt af, at formatet er ens hver gang, da min kode fjerner et bestemt antal karakterer fra de forskellige strenge. :)
Gravatar #55 - mazing
26. maj 2010 11:35
newz.dk slugte et par tegn af koden, så har smidt en kopi på pastebin for good measure.
Gravatar #56 - Windcape
26. maj 2010 12:05
Hvad med regulare expressions? :-)


string input = "020000112345678ATU1242515 000000014252+00000000+ 0200000000320803312345678DE118045186 000000000021982+0000000000000000+";
string pattern = @"(\d+)([12345678])(?<country>[A-Z]+)(?<first>\d+)(\s+)(?<second>\d+)(?<sign>\+|\-)";

Regex regex = new Regex(pattern);

foreach (Match match in regex.Matches(input))
{
Console.WriteLine("{0},{1},{2},{3}",
match.Groups["country"],
match.Groups["first"],
match.Groups["second"],
match.Groups["sign"]
);
}

Console.Read();


Output


ATU,1242515,000000014252,+
DE,118045186,000000000021982,+


Pastebin: http://pastebin.com/D9ZbVVSs
Gravatar #57 - XorpiZ
26. maj 2010 12:07
#56

Det er sgu til at få hovedpine af hehe. Jeg har absolut ingen anelse om, hvad der foregår :)
Gravatar #58 - Windcape
26. maj 2010 12:10
#57

Det er ret simpelt:


(\d+)([12345678])(?<country>[A-Z]+)(?<first>\d+)(\s+)(?<second>\d+)(?<sign>\+|\-)


?<groupName>

er named groups i .NET

\d+
\d er numre, fra 0 til 9, og + betyder flere af dem.

[A-Z]+
A-Z er som du kan gætte, bogstaver fra a-z i uppercase, og + er igen flere af dem.

\s
\s er whitespace.

\+|\-
Backslash bruges til escaping, så der står +|- altså, plus eller minus. | er "ellers" :-)
Gravatar #59 - XorpiZ
26. maj 2010 12:16
#58

Aha.... Det har jeg glemt, lige så snart jeg lukker fanebladet ned :)

Men det ser ellers smart ud!
Gravatar #60 - Spiderboy
26. maj 2010 12:20
XorpiZ (59) skrev:
Aha.... Det har jeg glemt, lige så snart jeg lukker fanebladet ned :)

Så skriv Windcapes forklaring som kommentar til koden. Netop derfor man kommenterer sin kode. :-)

XorpiZ (59) skrev:
Men det ser ellers smart ud!


Regulære udtryk er nemlig hammersmarte. Og lige dette problem er som skabt til dem. :-)
Gravatar #61 - Windcape
26. maj 2010 12:21
Gravatar #62 - Windcape
26. maj 2010 12:22
Spiderboy (60) skrev:
Så skriv Windcapes forklaring som kommentar til koden. Netop derfor man kommenterer sin kode. :-)
Neeeeeeeeeeeeeeeeeeeeeeeeeej!

Du skal dokumentere dine algortimer, ikke hvordan regex virker, i en kommentar.

I dette her tilfælde ville jeg inkludere en data-sample som kommentar, så programmøren nemmere kan lave tilrettelser.

Spiderboy (60) skrev:
Regulære udtryk er nemlig hammersmarte. Og lige dette problem er som skabt til dem. :-)
Præcist :-)
Gravatar #63 - mazing
26. maj 2010 12:25
Nu vi er inde på regex: http://www.txt2re.com/

Og her er hvad der sker, hver gang jeg prøver at sætte mig ordentlig ind i regexes: http://i.imgur.com/RUZHK.gif
Gravatar #64 - Windcape
26. maj 2010 12:27
mazing (63) skrev:
Og her er hvad der sker, hver gang jeg prøver at sætte mig ordentlig ind i regexes
Pjat. Det er fordi du forsøger at lære det hele på en gang.

De fleste mennesker kan forholde sig til "*.jpg", og det er næsten også regulare expressions!
Gravatar #65 - Spiderboy
26. maj 2010 12:29
Windcape (62) skrev:
Neeeeeeeeeeeeeeeeeeeeeeeeeej!

Du skal dokumentere dine algortimer, ikke hvordan regex virker, i en kommentar.

Ja, under normale omstændigheder, men når regulære udtryk er fuldstændigt nyt for en, kan det være ret overvældende at overskue, og netop derfor synes jeg han bør gøre det.

Kommentarer skal hjælpe programmøren med at forstå og overskue sin kode. Når han bliver fortrolig med regulære udtryk engang, kan han udelade det. :-)
Gravatar #66 - mazing
26. maj 2010 12:29
Ja, jeg har nu også brugt regular expressions før. Det er bare ikke en del af min standard toolbox af værktøjer jeg griber ud efter automagisk.

Jeg skulle jo bruge en undskyldning for at smide den gif ;)
Gravatar #67 - Windcape
26. maj 2010 12:31
Spiderboy (65) skrev:
Kommentarer skal hjælpe programmøren med at forstå og overskue sin kode.
Nej, det er faktisk forkert.

Kommentarer skal bruges til at hjælpe den næste programmør, med at forstå problemstillingen.

Det gøres best med sample af input, og en samle af output. Altså post #52 er ideelt set hvad der skal være kommentaren til koden.
Gravatar #68 - XorpiZ
26. maj 2010 12:36
Jeg kan godt høre, at RegEx er noget jeg skal have sat mig ind i på et tidspunkt :) Det er ihvf. en voldsomt mere elegant løsning end min egen!

Jeg har dog opdaget en lille fejl i outputtet:

ATU,1242515,000000014252,+


burde være

AT,U1242515,000000014252,+


da AT er landekoden og U1242515 er firmaets CVR-nummer. Det kan sikkert rettes uden det helt store bøvl dog.

Ang. kommentarer i koden, så plejer/plejede (da jeg programmerede i skolen) at kommentere de mere komplicerede dele af koden - og så lave et afsnit i starten hvor jeg beskrev formålet med programmet :)
Gravatar #69 - Spiderboy
26. maj 2010 12:36
#67
Det kan jeg egentlig godt følge dig i.

Men det fungerer kun, hvis hvis man har en erfaren programmør, som uden at blinke kunne finde på at hive eksempelvis regulære udtryk op af værktøjskassen, selv om det kan være en smule kringlet i forhold til så mange andre stykker værktøj.
Gravatar #70 - Windcape
26. maj 2010 12:41
XorpiZ (68) skrev:
Jeg har dog opdaget en lille fejl i outputtet:
Er landekoder altid 2 tegn? Fordi i så fald:

string pattern = @"(\d+)([12345678])(?<country>[A-Z]{2})(?<first>[A-Z0-9]+)(\s+)(?<second>\d+)(?<sign>\+|\-)"; 


Output:


AT,U1242515,000000014252,+
DE,118045186,000000000021982,+
Gravatar #71 - Windcape
26. maj 2010 12:44
Spiderboy (69) skrev:
Men det fungerer kun, hvis hvis man har en erfaren programmør
Det samme gælder alle teknologier/underteknologier

Men LINQ og Regex er nok de værste i .NET
Gravatar #72 - XorpiZ
26. maj 2010 12:45
#70

Smart man kan begrænse det på den måde!

Jeg er ved at være omvendt :)
Gravatar #73 - arne_v
26. maj 2010 13:49
mazing (53) skrev:

// Huston we have a spelling problem


:-)
Gravatar #74 - mazing
26. maj 2010 13:53
Grammarnazi! ;)
Gravatar #75 - onetreehell
26. maj 2010 17:44
#regular-expressions
http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html skrev:
Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.


Jeg mener man skal kommentere regexs hvis de er tilpas komplicerede. Man kan lave kommentarer inden i regexps i perl.
Gravatar #76 - Windcape
26. maj 2010 17:52
#75

Du skriver lige kommentarer til denne her så!

http://99-bottles-of-beer.net/language-perl-658.ht...
Gravatar #77 - onetreehell
26. maj 2010 17:54
#76
hvorfor?
Gravatar #78 - Windcape
26. maj 2010 17:55
#77

Ironi
Gravatar #79 - onetreehell
26. maj 2010 17:57
#78
???
Gravatar #80 - Windcape
26. maj 2010 17:59
Det er en regulare expression som udskriver 99 bottles of beer on the wall.

Det er jo netop så kompleks at man burde dokumentere den :p
Jeg vil ligefrem kalde den "write only".

(Men okay, perl er et "write only" sprog.)
Gravatar #81 - arne_v
26. maj 2010 18:04
#Perl og regex

Perl er sprogET for regex.

http://msdn.microsoft.com/en-us/library/hs600312.a...


In the .NET Framework, regular expression patterns are defined by a special syntax or language, which is compatible with Perl 5 regular expressions and adds some additional features such as right-to-left matching.


http://java.sun.com/javase/6/docs/api/java/util/re...


Comparison to Perl 5

The Pattern engine performs traditional NFA-based matching with ordered alternation as occurs in Perl 5.

Perl constructs not supported by this class:

...

Constructs supported by this class but not by Perl:

...

Notable differences from Perl:

...

Gravatar #82 - Windcape
26. maj 2010 18:07
Der er også POSIX regulare expressions, men jeg har aldrig set dem i brug uden for PHP. Og det var mest i PHP3.

http://dk2.php.net/manual/en/intro.regex.php
PHP also supports regular expressions using a Perl-compatible syntax using the PCRE functions. Those functions support non-greedy matching, assertions, conditional subpatterns, and a number of other features not supported by the POSIX-extended regular expression syntax.


http://dk2.php.net/manual/en/intro.pcre.php
The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5, with just a few differences (see below). The current implementation corresponds to Perl 5.005.


Gravatar #83 - arne_v
26. maj 2010 18:13
#82

Så se om kom igang med at blive Perl hacker.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login