Avatar billede charly Nybegynder
28. juni 2003 - 16:05 Der er 25 kommentarer og
1 løsning

kommaseparete endnu en gang.

Jeg har store problemer med at trække dataene ud fra denne kommaseparerede fil.

Her er et uddrag af den:

"000111111","Sort 4"",11.75,"STK",55,"121212"
"000111112","violet 4""",9.7,"STK",55,"121212"
"000111113","grøn,rød 4""",1587,"STK",55,"121212"
"000111114","sort",95.75,"STK",55,"121212"
"000111115","Sort,hvid 3""",625,"STK",55,"121212"

Det der driller mig er kommaet i farvefelt-tekststrengen. Derfor kan jeg ikke umiddelbart bruge split(str,",") funtionen. Desuden er der "(tommer) angivelsen. Den driller også en smule.

Er der nogle, der har et rigtig godt forslag til, hvordan man kan få trukket værdierne ud? Der vel egentlig sådan indholdet skal være, når værdierne er trukket ud af filen:

000111111 Sort 4" 11.75 STK 55 121212
000111112 violet 4" 9.7 STK 55 121212
000111113 grøn,rød 4" 1587 STK 55 121212
000111114 sort 95.75 STK 55 121212
000111115 Sort,hvid 3" 625 STK 55 121212
Avatar billede eagleeye Praktikant
28. juni 2003 - 16:32 #1
Prøv med dette så.:



do while not file.AtEndOfStream
  'Læs en linje i filen
  str = file.readline
 
  'Find føste og andet komma
  fk_pos = inStr(1,str,",")
  ak_pos = inStr(fk_pos+1,str,",")
  'Er karakteren efter andet komma et tal så split
  ' eller er der mere tekst efter det komma
  if isNumeric(mid(str,ak_pos+1,1)) then
    strArr = Split(str, ",")
  else
    Set strArr = Nothing
    redim strArr(0)
    strArr(0) = mid(str,1,fk_pos-1)
    redim preserve strArr(ubound(strArr)+1)
    ak_pos = inStr(ak_pos+1,str,",")
    strArr(1) = mid(str,fk_pos+1,ak_pos-fk_pos-1)
    str = mid(str,ak_pos+1)
    tempArr = Split(str,",")
    for i = lbound(tempArr) to ubound(tempArr)
      redim preserve strArr(ubound(strArr)+1)
      strArr(ubound(strArr)) = tempArr(i)
    next
  end if
 
 
  'Test udskrift
  for i = lbound(strArr) to ubound(strArr)
    Response.Write strArr(i) & " "
  next
  Response.Write "<br>"
   
loop
file.Close
Set file = Nothing
Set FSO = Nothing
Avatar billede charly Nybegynder
28. juni 2003 - 16:42 #2
Tak det virker 'næsten perfekt'

Der er dog stadig "" rundt og tekststrengene. Dem kan jeg umiddelbart ikke bare fjerne via en replace, da der jo eksempelvis stadig gerne skulle stå

000111111 Sort 4" 11.75 STK 55 121212

"(tomme) ville jo også blive 'replacet' i den forbindelse.
Avatar billede erikjacobsen Ekspert
28. juni 2003 - 17:00 #3
Er det en engangskonvertering, og du vil sende den til mig, så klarer
jeg det for dig med et simpelt script i Perl.
Avatar billede eagleeye Praktikant
28. juni 2003 - 17:04 #4
Ok så prøv at tilføje dette:

  'Fjerner " og " fra start og slut
  for i = lbound(strArr) to ubound(strArr)
    if Left(strArr(i),1)="""" AND Right(strArr(i),1)="""" then
      strArr(i) = Mid(strArr(i),2,len(strArr(i))-2)
    end if
  next


Så det bliver:

do while not file.AtEndOfStream
  str = file.readline
 
  fk_pos = inStr(1,str,",")
  ak_pos = inStr(fk_pos+1,str,",")
  if isNumeric(mid(str,ak_pos+1,1)) then
    strArr = Split(str, ",")
  else
    Set strArr = Nothing
    redim strArr(0)
    strArr(0) = mid(str,1,fk_pos-1)
    redim preserve strArr(ubound(strArr)+1)
    ak_pos = inStr(ak_pos+1,str,",")
    strArr(1) = mid(str,fk_pos+1,ak_pos-fk_pos-1)
    str = mid(str,ak_pos+1)
    tempArr = Split(str,",")
    for i = lbound(tempArr) to ubound(tempArr)
      redim preserve strArr(ubound(strArr)+1)
      strArr(ubound(strArr)) = tempArr(i)
    next
  end if
  'Fjerner " og " fra start og slut
  for i = lbound(strArr) to ubound(strArr)
    if Left(strArr(i),1)="""" AND Right(strArr(i),1)="""" then
      strArr(i) = Mid(strArr(i),2,len(strArr(i))-2)
    end if
  next
 
 
  'Test udskrift
  for i = lbound(strArr) to ubound(strArr)
    Response.Write strArr(i) & " "
  next
  Response.Write "<br>"
   
loop
Avatar billede charly Nybegynder
28. juni 2003 - 17:40 #5
Hej eagleeye,

Her er et uddrag af resultatet! Den brækker sig ved sidstnævnte record.

000133106 S.TEE M/N/M 3/4"" 60.7 STK 55 050403
000165406 GALV.TERMOMETERTEE 20 MM 115 STK 55 050403
000165408 "G.TEE 45GR.GREN 1""" 173 STK 55 050403

Microsoft OLE DB Provider for ODBC Drivers error '80040e10'

[Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 1.

/test/admin/admin_opdater_db.asp, line 69

Det er ligesom om at det forskubber sig ved sidstnævnte record.
Her er et udrag af den oprindelig fil:

"000133106","S.TEE M/N/M      3/4""",60.7,"STK",55,"050403"
"000133406","GALV.BUKSETEE 20 MM",76,"STK",55,"050403"
"000165408","G.TEE,45GR.GREN    1""",173,"STK",55,"050403"

ps.  til erikjacobsen: Nej, det skal opdateres jævnligt, ellers tak :-)
Avatar billede charly Nybegynder
28. juni 2003 - 17:47 #6
I øvrigt kan jeg sagtens importere udtrækket fejlfrit i eksempelvis en Access db.

Gad vide, hvilken tekstkvafilikator de bruger? :-) Der må være en mere systematisk vej at nedbryde sådan en kommasepareret fil på!
Avatar billede eagleeye Praktikant
28. juni 2003 - 18:20 #7
Ja det rykker sig i denne linje:

"000165408","G.TEE,45GR.GREN    1""",173,"STK",55,"050403"

Det er fordi der er et tal 4 lige efter kommaet. Så det ikke længere nok med at tolke et tal som værne OK lige efter kommaet.

så kan man lave det om så den skal kigge efter ,TALTAL, for at man ved tallet ikke er en del af teksten mellem " og ". Men det holder sikkert heller ikke i længden da det nok vil opstå før eller siden: "G.TEE,45,67GR.GREN"
Avatar billede erikjacobsen Ekspert
28. juni 2003 - 18:22 #8
Jeg har gjort det før, fejlfrit. Sku' jeg?
Avatar billede charly Nybegynder
28. juni 2003 - 18:30 #9
Kunne man så ikke gøre noget andet i stedet?

Kan man ikke lave noget kode, som tjekkede om der var kommaer inden for "" og så replace disse kommaer med et andet tegn! Efter følgende ville en split(str,",") jo fungere!

Kan det lade sig gøre?
Avatar billede eagleeye Praktikant
28. juni 2003 - 18:34 #10
Ja det vil viker nogle gange det kommer an på hvad stengene indeholder.

Problemmet er man ikke i den streng du har har en klar definition af hvor man kan dele strengen.

Hvis du har en streng som denne:

"000165408","G.TEE,45,46GR.GREN    1"",173,"STK",55,"050403"

Så kan man ikke antage at det skal være et tal efter komma.

Problemmet med at søge mellem " og " er at hvis der står 4"(tommer) så vil " fra tommer tolkes som slut "
Avatar billede charly Nybegynder
28. juni 2003 - 18:37 #11
enig, men er ""'erne ikke parvis i datasættet?

"000165408","G.TEE,45,46GR.GREN    1""",173,"STK",55,"050403"
Avatar billede eagleeye Praktikant
28. juni 2003 - 18:45 #12
Nej det er bare en måde man kan skrive en " i en streng. Hvis man vil skrive
Hej "gamle" dreng  i en tekst streng så skriver men to "" efter hinandn i stengen:
str = "Hej ""gamgle"" dreng"

men der er kun en " i strengen.

så der kunne også være:

"000165408","G.TEE,45,46GR.GREN    1" rund",173,"STK",55,"050403"

Alternativ kan der være , efter et (tomme) tegn?
Eller så må det regexp du fik den anden da laves om så den ikke kun søger efter " men  ",TALTAL," som slut på strengen...
Avatar billede eagleeye Praktikant
28. juni 2003 - 18:50 #13
Jeg har rette i dun function du fik sidst:

Det samme nu laver den det komma om til mølle, og den søger efter

",TALTAL,"  som slut på strengen som må indehold komma.


Function SplitStr(str)
  Dim re, strTmp
  Set re = New RegExp
  re.Pattern = "(""[\w\d\s]+),([\w\d\s]+"",[\d.]+,"")"
  re.Global = true
  strTmp = re.Replace(str, "$1¤$2")
  SplitStr = Split(strTmp,",")
End Function
Avatar billede eagleeye Praktikant
28. juni 2003 - 18:53 #14
Så din kode bliver:



Function SplitStr(str)
  Dim re, strTmp
  Set re = New RegExp
  re.Pattern = "(""[\w\d\s]+),([\w\d\s]+"",[\d.]+,"")"
  re.Global = true
  strTmp = re.Replace(str, "$1¤$2")
  SplitStr = Split(strTmp,",")
End Function


Set FSO = Server.CreateObject("Scripting.FileSystemObject")
Set file = FSO.OpenTextFile(Server.MapPath("xxx"))

do while not file.AtEndOfStream
  str = file.readline

  'den splittes med den nye funktion
  strArr = SplitStr(str)
 
  ' hvert element i arrayet udskrives - men først udskiftes møllehjul igen med komma
  For i = lbound(strArr) to ubound(strArr)
    strArr(i) = Replace(strArr(i),"¤",",")
    if Left(strArr(i),1)="""" AND Right(strArr(i),1)="""" then
      strArr(i) = Mid(strArr(i),2,len(strArr(i))-2)
    end if
  Next



  'Test udskrift
  for i = lbound(strArr) to ubound(strArr)
    Response.Write strArr(i) & "<br> "
  next
  Response.Write "<br>"

loop
Avatar billede charly Nybegynder
28. juni 2003 - 19:02 #15
Ja så brokker den sig over den go'e gamle:

"000001416","G.BJNING,LANG      4""",1587,"STK",55,"050403"

Jeg sætter pris på din tålmodighed! Jeg gad godt at kunne snage i hvordan, MS Access får det udtræk ind i db'en.

Jeg har det bare sådan, at dem der har lavet det her udtræk må ha' en grund til at lave det som det er lavet.

Kunne de ikke bare ha' separeret det med '¤' i stedet for ',' :-)
Avatar billede charly Nybegynder
28. juni 2003 - 19:08 #16
Hov,

du skrev
---------------
Nej det er bare en måde man kan skrive en " i en streng. Hvis man vil skrive
Hej "gamle" dreng  i en tekst streng så skriver men to "" efter hinandn i stengen:
str = "Hej ""gamgle"" dreng"

men der er kun en " i strengen.
-------------
Der er faktisk 2 " i strengen. Se her:

"000165408","G.TEE,45,46GR.GREN    1""",173,"STK",55,"050403"

Giver det så mere system i tingene?
Avatar billede erikjacobsen Ekspert
28. juni 2003 - 19:46 #17
Ja, undskyld jeg blander mig med noget irrelevant, men dette minder mig
lidt om en diskussion at bruge det rigtige værktøj. I mine øjne er det
regulære udtryk, og så også Perl (der er regulære udtryk andre steder).

Jeg fandt et gammelt script, jeg har brugt før. tilpassede en linie, og
satte separator-tegnet mellem felterne til semikolon. Scriptet er:

$s='"(?:[^"]|"")*"';
$d='\d+(?:\.\d+)?';
while (<>) {
  /^($s),($s),($d),($s),($d),($s)$/ or die("FEJL: $_\n");
  @a=($1,$2,$3,$4,$5,$6);
  for (@a) { s/""/"/g; s/^"(.*)"$/\1/; }
  print join(';',@a)."\n";
}

og output er med det eksempel, der er givet:

000111111;Sort 4";11.75;STK;55;121212
000111112;violet 4";9.7;STK;55;121212
000111113;grøn,rød 4";1587;STK;55;121212
000111114;sort;95.75;STK;55;121212
000111115;Sort,hvid 3";625;STK;55;121212

som skulle kunne splittes på semikolon.
Avatar billede charly Nybegynder
28. juni 2003 - 20:14 #18
Udemærket erikjacobsen,

Men har du noget, der kan anvendes i ASP (til os dødelige)? :-)
Avatar billede erikjacobsen Ekspert
28. juni 2003 - 20:47 #19
Nej :) Men ASP har også regulære udtryk i dag - jeg gider bare ikke
sætte mig ind i hvordan man gør. Men som sagt - jeg kan køre din fil
igennem scriptet.

PS: Jeg er vist også dødelig.
Avatar billede eagleeye Praktikant
28. juni 2003 - 23:39 #20
Så prøv med dette:



Set FSO = Server.CreateObject("Scripting.FileSystemObject")
Set file = FSO.OpenTextFile(Server.MapPath("xxxx.txt"))

s = "(?:[^""]|"")*"
d = "\d+(?:\.\d+)?"
Set re = New RegExp
re.Global = true

do while not file.AtEndOfStream
  str = file.readline

  re.Pattern = "^""(" &s& ")"",""(" &s& ")"",(" &d& "),""(" &s& ")"",(" &d& "),""(" &s& ")""$"
  str = re.Replace(str, "$1;$2;$3;$4;$5;$6")
 
  re.Pattern = """"""
  str = re.Replace(str, """")

 
  'Nu kan der splittes på ;
  strArr = Split(str,";")


  'Udskriv for test
  for i = lbound(strArr) to ubound(strArr)
    Response.write strArr(i) & "<br>" 
  next
 
  Response.write "<br>"
loop
Avatar billede charly Nybegynder
29. juni 2003 - 14:17 #21
Den kommer igennem hele filen på nær denne record:

"353945248","LINDAB RED. FCFU 250-160",1,"STK",-100,"050403"

Der er over 20.000 records, så det er sgu godt gået!

Jeg har valgt at bare springe over denne record i mit gennemløb, så den må de sgu undvære :-)

Jeg siger mange tak for hjælpen.
Avatar billede erikjacobsen Ekspert
29. juni 2003 - 14:21 #22
Du skriver bare

d = "-?\d+(?:\.\d+)?"
Avatar billede charly Nybegynder
29. juni 2003 - 14:42 #23
It works!

Jeg ved godt, at det her ikke er edb-skolen, men kan du kort forklare hvad dette udtryk betyder:

"-?\d+(?:\.\d+)?"

Jeg kender ikke rigtig til begrebet 'regulære udtryk'.
Avatar billede erikjacobsen Ekspert
29. juni 2003 - 14:47 #24
Det ville tage lidt tid at forklare. Prøv at kigge i PHP-manualen.

Men regulære udtryk er menneskehedens bedste opfindelse siden
hakkejernet, biograffilem og isvaflen.  ;)
Avatar billede erikjacobsen Ekspert
29. juni 2003 - 14:48 #25
...og den automatiske stavekontrol
Avatar billede charly Nybegynder
29. juni 2003 - 14:48 #26
:-)

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