[C#] Woorden uit een file halen

Pagina: 1
Acties:
  • 191 views sinds 30-01-2008
  • Reageer

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Ik ben nu bezig een soort IndexServer in C# te schrijven en daarvoor wil ik dus alle woorden uit een file in een SQL-database zetten. Ik heb al getest met een aantal testfiles en het werkt op zich perfect (elk woord komt maar 1 keer in de DB en wordt gekoppeld aan verschillende bestanden).
Ook bij het aanmaken van nieuwe bestanden, wijzigen van bestanden, verwijderen werkt het allemaal goed.

Maar nu moet ik dus de files gaan parsen. De testfiles bestonden gewoon uit pure tekst.
Hoe kan ik nu het beste zo'n file (bijv. asp) gaan parsen ?
Voor de testfiles had ik gewoon iets als:
- file inlezen in een string
- alle punten in de string vervangen door een spatie
- alle komma's in de string vervangen door een spatie
- alle enters (\r\n) in de string vervangen door een spatie
- de string 'splitten' op elke spatie --> een string[] van alle woorden

Maar nu wil ik dus ook alle tekst tussen bijv. '<%' en '%>' eruit gaan filteren.
Misschien is het dan gewoon beter om de hele string te doorlopen en elke keer als ik een leesteken tegenkomen een nieuwe string toevoegen aan een array en die aanvullen totdat ik weer een leesteken tegenkomen.
Als ik dan '<%' tegenkom, kan ik gewoon doorgaan zonder het bij te houden (geen nieuwe string in de array dus) totdat ik de '%>' tegenkom.
Werkt dit sneller dan alles replacen of juist trager?

Of misschien een heel andere manier?
En wat is de makkelijkste manier om alle leestekens uit een string te halen? Mijn manier kan wat makkelijker door die replace-regel in een loop te zetten die door alle tekens <'a' en >'Z' (of juist <'A' en >'z') loopt. Maar kan dat nog makkelijker?

En hoe kan ik het zo makkelijk mogelijk maken om filetypes toe te voegen?
Ik zat zelf te denken aan een xml-file met daarin een aantal tags met de lettercombinaties waar op gelet moet worden.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Als ik jou was ging ik gewoon karakter voor karakter die string bijlangs en nam een lijst me waarin je de gevonden woorden gaat plaatsen. Je blijft net zo lang nieuw woord vormen als er goeie karakter zijn, daarna plaats je dit woord in die lijst en blijft karakters negeren totdat je weer een goeie tegenkomt en dan kan je weer beginnen met een woord vormen.

[edit]
Als je eerst de comma`s eruit gaat filteren, en daarna de punten etc, dan moet je dus voor iedere conversie die tekst doorlopen. En dat is natuurlijk zonde van de tijd.

[edit2]
toverwoord = DFA

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Maar de replace-functie op zich is wel weer een heel stuk sneller dan handmatig de tekst doorlopen.
Maar ik zat inderdaad ook al wel aan deze methode te denken ja.

En wie is DFA ?
Ik ken de DFA alleen als de Daily Female Appriciation op www.wtfpeople.com (elke dag een foto van een lekkere babe). :)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

maikel schreef op 10 november 2002 @ 16:25:
Maar de replace-functie op zich is wel weer een heel stuk sneller dan handmatig de tekst doorlopen.
Waarom zou dat sneller zijn?
En wie is DFA ?
Deterministic Finite Automata

Je gaat mbv een toestand diagram al je toestanden beschreven en wat nodig is om van de ene naar de andere toestand te komen. Aan de hand hiervan kan je heel eenvoudig een algoritme schrijven.

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Alarmnummer schreef op 10 November 2002 @ 16:45:
[...]

Waarom zou dat sneller zijn?
Omdat dat een standaard-functie is. :)
Ik neem aan dat die wat meer geoptimaliseerd zijn dan wanneer ik het zelf doe. Misschien dat die onderhuids wat directer met het geheugen werkt of zo.

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Weet iemand waar ik wat meer, goede info kan vinden over DFA's ??
Het enige wat ik kan vinden zijn opgaven van uni's en zo. Maar dus niet een duidelijke uitleg over hoe het te leren.

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Is er dan helemaal niemand die hier wat meer vanaf weet ?

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
google weet er wel veel vanaf.

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Daar heb ik al een hoop gezocht, maar die komt vooral aan met opgaven voor uni's of informatie over DFA's waarbij er vanuit wordt gegaan dat je ze al kunt opzetten.
Maar nergens kon ik echt wat vinden die het vanaf het begin (voor een newbie op dat gebied dus) behandeld.

Verwijderd

Het principe is niet zo heel ingewikkeld, en Alarmnummer vatte het eigenlijk wel goed samen.

In een variabele bewaar je een state (maak hier bijvoorbeeld een enum voor). Deze state bevat in welke staat je programma/parser zich op dat moment bevindt :P

Voorbeeldje:

States: InWord, InASPCode, WordSeparator

Tekst:
code:
1
2
3
4
5
Hallo, dit is test tekst.
<%
' met ASP code
%>
bla bla bla!

Je zet je state eerst op WordSeparator, dan ga je de tekst door werken...

Als eerste kom je een letter tegen, je state veranderd naar InWord. Je kijkt of er bij deze overgang iets moet gebeuren, in dit geval waarschijnlijk niet, je slaat de letter op in een StringBuilder. Je gaat een letter verder, slaat die op, etc. tot je een niet-letter tegenkomt (de eerste in dit geval is een komma). Die valt onder de word seperators. Je schakelt nu over naar WordSeparator. Moet er nu iets gebeuren? Ja, je woord moet aan de index toegevoegd worden en je StringBuilder moet weer leeg. Goed, dit herhaal je een paar keer. Dan kom je <% tegen, oh! we schakelen over naar InASPCode, moet er wat gebeuren? misschien wel, dat hangt van je vorige state af. Nu loop de tekst door, je komt een enter tegen, we zitten in asp code dus daar doen we niets mee, zo loop je door tot je %> komt. Ah! Einde ASP code, we schakelen weer over naar WordSeparator. Moeten we iets doen? Waarschijnlijk niet. En zo ga je dan door tot het eind van je bestand.

HTH :)

edit:
Ik hoop trouwens dat ik dit goed onthouden heb allemaal, iig is dit wel een methode die werkt lijkt me :)

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Aha. Thanks !!
Ik had dus eigenlijk zelf ook al zoiets bedacht. :)
Maar via Google kwam ik steeds allerlei diagrammen tegen en zo. Naast de state-diagram ook nog een tabelletje of zo. :?
Overigens wordt het nog wel iets lastiger aangezien je, als je per teken er doorheen loopt, geen <% tegenkomt. Dus je moet dan ook nog onthouden wat het laatste teken was.
En bij bijv. <!-- moet je onthouden wat de vorige 3 teken waren.
Of vang je dat weer af door daar 4 verschillende states van te maken ? Bijv: states (comment1, comment2, comment3, comment4) ??

Verwijderd

maikel schreef op 14 november 2002 @ 20:50:
Overigens wordt het nog wel iets lastiger aangezien je, als je per teken er doorheen loopt, geen <% tegenkomt. Dus je moet dan ook nog onthouden wat het laatste teken was.
En bij bijv. <!-- moet je onthouden wat de vorige 3 teken waren.
Of vang je dat weer af door daar 4 verschillende states van te maken ? Bijv: states (comment1, comment2, comment3, comment4) ??
Ik zou dan vooruit gaan lezen (het makkelijkst is dan ook je hele file in 1 lange string te gooien).

  • maikel
  • Registratie: Januari 2001
  • Laatst online: 28-08 13:52
Zoiets doe ik nu inderdaad al. Maar is het dan volgens de DFA-methode niet zo dat ik daar verschillende states voor krijg?

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
maikel schreef op 16 november 2002 @ 12:45:
Zoiets doe ik nu inderdaad al. Maar is het dan volgens de DFA-methode niet zo dat ik daar verschillende states voor krijg?
inderdaad, dat kun je bv zo doen:

Afbeeldingslocatie: http://members.home.nl/klimstra/statechart.png

Bij de overgangen staat 'x / y'. x is de conditie, in dit geval het huidige teken.y is de actie die uitgevoerd wordt bij de transitie. Als x er niet staat wordt de transitie uitgevoerd als de andere vanuit de state dat niet worden, dus een default case zeg maar (lambda transitie). Het zwarte bolletje is trouwens de beginstate.

Verwijderd

Je kunt de file ineens in memory laden, en dan aan de hand van de Regular expression engine (dat is een NFA tenslotte :P) gaan matchen en dmv de Matches method van de RegularExpression een MatchCollection verkrijgen, die je dan gebruikt voor het distilleren van de woorden die je wilt herkennen (dus je matcht bv alle whitespace en alle niet te indexeren woorden eruit en de rest indexeer je). Een scanner zelf maken is, wanneer je het goed wilt doen, niet 1 2 3 gedaan, want je belandt dan al snel op het traject van de gemiddelde Lexical Analyzer en die solide bouwen kost veelal nogal wat tijd.
Pagina: 1