25. september 2003 - 17:09Der er
61 kommentarer og 1 løsning
Hvis ord indgår i streng, så lav ordet til link
Hejsa,
Nogen der kan gennemskue følgende:
<ord> |- id(primær) |- ord |- forklaring
lad os sige at ordet 'cykel' og ordet 'bil' er poster i tabellen <ord>
så har vi en streng i asp - lad os kalde den test : test = "Drengen kom kørende på en cykel, men ville egentlig hellere køre bil"
Nu ønsker jeg så en funktion der tager 'test' som parameter og scanner den igennem for alle ord der findes i <ord> tabellen og hvis der er en match, som der jo er her, skal funktionen spytte en modificeret streng ud, hvor de matchende ord er lavet til link ála <a href="ord.asp?id=1">cykel</a> og <a href="ord.asp?id=2">bil</a> osv osv...
Sådan en funktion kan jeg godt lave. Din tabel med ord: Kan jeg antage, at den findes som et array af ord: ord(0), ord(1),...,ord(n) ?? Metoden vil så være: først erstattes tegnene '.', ',' ';' etc med blanktegn. Derefter fjernes alle overflødige blanktegn, og der sørges for at ordene i teksten kun er adskilt af et blanktegn. Derefter løbes ordlisten igennem og der testes om et ord forekommer i teksten. Hvis det er tilfældet tilføjes et sådant ord til et array af ord med link.
Jeg vil gå ud fra, at hvis teksten er 'havemanden slår græs', så er der kun 3 ord her. Altså ordene 'have' og 'manden' skal ikke regnes som ord, selv om der måtte være med i din ord-tabel.
Er teksterne korte? Altså blot nogel få linier? Eller er der tale om meget lange tekster?
Jeg er nødt til at stoppe nu, men jeg vil komme med et forslag sent i aften.
Synes godt om
Slettet bruger
25. september 2003 - 18:24#2
Ja, du kan gå ud fra at ordene ligger i én dimension arrRecords(0,n) og id'et i den anden dimension arrRecords(1,n) Teksterne er vilkårligt lange/korte.. Som sådan er det vel mest hensigtsmæssigt hvis funktionen tager højde for ordene på denne måde. Eksempel : ord = socialisering HVIS 'socialisering' findes som helt ord i array SÅ lav link til <socialisering> ELLERSHVIS 'social' findes som helt ord i array og funktionen støder på 'socialarbejder' i texten og 'socialarbejder' ikke indgår som helt ord SÅ lav link til <social> men skriv stadig hele ordet...
Jeg laver først en løsning, hvor der kun laves link, når der er tale om sammenfald af hele ord. ordet socialarbejder indeholder f.eks. følgende ord: so, i, al, ar, arbejde, arbejder, er, ej, der, be, de. Og det er vel ikke meningen, at lave så mange link, hvis socialarbjder ikke selv findes i ordtabellen, men de andre ord er med?
Synes godt om
Slettet bruger
25. september 2003 - 21:45#4
hmm, det er svært at lure... Somewhere in between ;) Måske hvis ordet er længere end 4 chars..?
Her er så et forslag i form af et Vbscript. Gem det som en tekstfil med navnet Link.vbs. Hvis du klikker på den får dur testet. Du skal selvfølgelig fjerne de sidste linier, når det skal bruges i ASP-sammenhæng.
Option Explicit dim tekst, ord(4,1), n, Liste(), i
'Her er en samling af specielle tegn, der skal fjernes. const tegn=".,;:""!?/01234567898)("
'Test-eksempel: tekst="Der var engang en mand, han bo-" & VBCrLf tekst=tekst & "ede i en spand. Spanden var af ler, og" & VBCrLf tekst=tekst & "konen vaskede bleer. Nu kan jeg ikke mer"
sub fjerntegn dim i for i=1 to len(tegn) tekst=Replace(tekst,mid(tegn,i,1)," ") next tekst=Replace(tekst,"-" & VBCrLf,"") 'Orddeling ved linieskift håndteres her tekst=Replace(tekst,VBCrLf," ") tekst=trim(Lcase(tekst)) while InStr(tekst," ")>0 tekst=Replace(tekst," "," ") wend end sub
sub LavListe dim p fjerntegn tekst=" " & tekst & " " for i=0 to n if InStr(tekst," " & Lcase(ord(i,0)) & " ")>0 then Liste(p)="<a href=""ord.asp?id=" & ord(i,1) & """>" & ord(i,0) & "</a>" p=p+1 end if next redim preserve Liste(p-1) end sub
(Hvis din ordtabel er meget stor, bør funktionen Link(ord) nedenfor laves om. For at afgøre, om et ord er i listen gennemløbes den blot fra en ende af. Det kan gøres mere effektivt)
Option Explicit dim tekst, ordTbl(4,1) tekst="Der var engang en mand. Han boede i en spand." & VBCrLf & _ "Spanden var af ler og konen vasked bler." & VBCrLf & _ "Nu kan jeg ikke mer." ordTbl(0,0)="engang": ordTbl(0,1)=1 ordTbl(1,0)="blå": ordTbl(1,1)=2 ordTbl(2,0)="En": ordTbl(2,1)=3 ordTbl(3,0)="ble": ordTbl(3,1)=4 ordTbl(4,0)="spande": ordTbl(4,1)=5
function Link(ord) dim i for i=0 to Ubound(ordTbl,1) if Lcase(ordTbl(i,0))=Lcase(ord) then Link="<a href=""ord.asp?id=" & ordTbl(i,1) & """>" & ord & "</a>" exit function end if next Link=ord end function
function LinkTekst(tekst) dim p, ord, tmp, ch,L const Bgst="abcdefghijklmnopqrstuvvwyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" p=1: L=len(tekst) while p<=L ch=mid(tekst,p,1):p=p+1 while Instr(Bgst,ch)>0 and p<=L ord=ord & ch ch=mid(tekst,p,1) p=p+1 wend if ord<>"" then tmp=tmp & Link(ord) & ch ord="" else tmp=tmp & ch end if wend LinkTekst=tmp end function
msgbox LinkTekst(tekst)
Synes godt om
Slettet bruger
26. september 2003 - 08:50#10
det ser jo superfedt ud, men du har nok ret i at gennemløbet af ordlisten bør rationaliseres, så den ikke bare tæsker lineært der ud af... For der kommer til at være pænt mange ord :)
Synes godt om
Slettet bruger
26. september 2003 - 08:58#11
har lige prøvet og det virker ikke helt efter hensigten når jeg bruger det i asp
tekst = "Drengen troede at han kørte på en cykel, men ville hellere køre bil, men så var det en færge" SQL = "SELECT id, ord FROM ord" Set rs = Conn.Execute(SQL) if not rs.eof then arrOrd = rs.getrows() end if rs.close set rs = nothing
function Link(ord) dim i for i=0 to Ubound(arrOrd,1) if Lcase(arrOrd(i,0))=Lcase(ord) then Link="<a href=""ord.asp?id=" & arrOrd(i,1) & """>" & ord & "</a>" exit function end if next Link=ord end function
function LinkTekst(tekst) dim p, ord, tmp, ch,L const Bgst="abcdefghijklmnopqrstuvvwyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" p=1: L=len(tekst) while p<=L ch=mid(tekst,p,1):p=p+1 while Instr(Bgst,ch)>0 and p<=L ord=ord & ch ch=mid(tekst,p,1) p=p+1 wend if ord<>"" then tmp=tmp & Link(ord) & ch ord="" else tmp=tmp & ch end if wend LinkTekst=tmp end function
Response.write LinkTekst(tekst)
returnerer Drengen troede at han kørte på en <a href="ord.asp?id=Bil">cykel</a>, men ville hellere køre bil, men så var det en færge, men måske har det noget at gøre med initialiseringen af mit array at gøre?
Ja, det må være det. <a href="ord.asp?id=Bil">cykel</a>, id=Bil??? Det burde jo have været et tal! Så dit array har en forkert opbygning i forhold til det jeg har regnet med.
Hvor mange ord vil der være i din ordtabel?
Synes godt om
Slettet bruger
26. september 2003 - 09:30#14
Du kan se i det jeg lige pastede, hvordan mit array er opbygget :) Jeg tror der er nok ord til at søgningen ikke bør være sekventiel.
sql=..id,ord... Mon ikke du har fået byttet om på ord og ID-numre?
Synes godt om
Slettet bruger
26. september 2003 - 10:12#16
hvis jeg ændrer SQL = "SELECT ord, id FROM ord" og Link="<a href=""ord.asp?id=" & arrOrd(1,i) & """>" & ord & "</a>" virker det, men den når kun til cykel : Drengen troede at han kørte på en <a href="ord.asp?id=1">cykel</a>, men ville hellere køre bil, men så var det en færge
jeg har lavet en fejl, som gør, at færge ikke kommer med:
Linien
while Instr(Bgst,ch)>0 and p<=L
skal rettes til
while Instr(Bgst,ch)>0 and p<=L+1
Prøv med teksten: En bil kom kørende. Drengen troede at han kørte på en cykel, men ville hellere køre bil, men så var det en færge
Synes godt om
Slettet bruger
26. september 2003 - 10:54#18
tekst = "En bil kom kørende. Drengen troede at han kørte på en cykel, men ville hellere køre bil, men så var det en færge" SQL = "SELECT ord, id FROM ord" Set rs = Conn.Execute(SQL) if not rs.eof then arrOrd = rs.getrows() end if rs.close set rs = nothing
function Link(ord) dim i for i=0 to Ubound(arrOrd,1) if Lcase(arrOrd(i,0))=Lcase(ord) then Link="<a href=""ord.asp?id=" & arrOrd(1,i) & """>" & ord & "</a>" exit function end if next Link=ord end function
function LinkTekst(tekst) dim p, ord, tmp, ch,L const Bgst="abcdefghijklmnopqrstuvvwyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" p=1: L=len(tekst) while p<=L ch=mid(tekst,p,1):p=p+1 while Instr(Bgst,ch)>0 and p<=L+1 ord=ord & ch ch=mid(tekst,p,1) p=p+1 wend if ord<>"" then tmp=tmp & Link(ord) & ch ord="" else tmp=tmp & ch end if wend LinkTekst=tmp end function
Prøv lige at lave ordtabellen manuelt: dim arrOrd(3,1) arrOrd(0,0)="bil": arrOrd(0,1)=1 arrOrd(1,0)="cykel": arrOrd(1,1)=2 arrOrd(2,0)="færge": arrOrd(2,1)=3 arrOrd(3,0)="drengen": arrOrd(3,1)=4
men prøv allerførst at få udskrevet Ubound(arrOrd,1), men også gerne din ordtabel.
Jeg tro din ordtabel er på den anden led. Derfor er det ikke Ubound(arrOr,1), men Ubound(arrOrd,2) du skal bruge.
Synes godt om
Slettet bruger
26. september 2003 - 13:22#22
response.write Ubound(arrOrd,1) = 1 og det manuelle kan jeg ikke få til at virke..
Synes godt om
Slettet bruger
26. september 2003 - 13:35#23
altså, det her virker fint nok
dim tekst, ordTbl(4,1) tekst="Der var engang en mand. Han boede i en spand." & VBCrLf & _ "Spanden var af ler og konen vasked bler." & VBCrLf & _ "Nu kan jeg ikke mer." ordTbl(0,0)="engang": ordTbl(0,1)=1 ordTbl(1,0)="blå": ordTbl(1,1)=2 ordTbl(2,0)="En": ordTbl(2,1)=3 ordTbl(3,0)="ble": ordTbl(3,1)=4 ordTbl(4,0)="spande": ordTbl(4,1)=5
function Link(ord) dim i for i=0 to Ubound(ordTbl,1) if Lcase(ordTbl(i,0))=Lcase(ord) then Link="<a href=""ord.asp?id=" & ordTbl(i,1) & """>" & ord & "</a>" exit function end if next Link=ord end function
function LinkTekst(tekst) dim p, ord, tmp, ch,L const Bgst="abcdefghijklmnopqrstuvvwyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" p=1: L=len(tekst) while p<=L ch=mid(tekst,p,1):p=p+1 while Instr(Bgst,ch)>0 and p<=L ord=ord & ch ch=mid(tekst,p,1) p=p+1 wend if ord<>"" then tmp=tmp & Link(ord) & ch ord="" else tmp=tmp & ch end if wend LinkTekst=tmp end function
Response.write LinkTekst(tekst)
nu skal det så bare spille sammen med tabellen i databasen :)
hvor ordtabellen er lavet manuelt således: dim arrOrd(3,1) arrOrd(0,0)="bil": arrOrd(0,1)=1 arrOrd(1,0)="cykel": arrOrd(1,1)=2 arrOrd(2,0)="færge": arrOrd(2,1)=3 arrOrd(3,0)="drengen": arrOrd(3,1)=4
har du prøvet at udskrive Ubound(arrOrd,2) Problemet er blot at få dine data ind i en tabel, som vi har styr på.
Synes godt om
Slettet bruger
26. september 2003 - 13:47#28
Hvis tabellen opbygges m SQL = "SELECT ord, id FROM ord" Set rs = Conn.Execute(SQL) if not rs.eof then arrOrd = rs.getrows() så returnerer response.write Ubound(arrOrd,2) bare "2"
prøv at få udskrevet i stedet arrOrd(0,0), arrOrd(1,0) arrOrd(0,1), arrOrd(1,1) arrOrd(0,1), arrOrd(2,2)
Din ordtabel er vendt om. Så du skal blot benytte Ubound(arrOrd,2) og arrOrd(i,1) skal nu være arrord(1,i) i går fra 0 til 2. Du har altså kun de 3 ord bil, cykel og færge med lige nu.
function Link(ord) dim i for i=0 to Ubound(arrOrd,2) if Lcase(arrOrd(0,i))=Lcase(ord) then Link="<a href=""ord.asp?id=" & arrOrd(1,i) & """>" & ord & "</a>" exit function end if next Link=ord end function
Synes godt om
Slettet bruger
26. september 2003 - 13:58#35
jeps,
så nu ser den således ud
function Link(ord) dim i for i=0 to Ubound(arrOrd,2) if Lcase(arrOrd(0,i))=Lcase(ord) then Link="<a href=""ord.asp?id=" & arrOrd(1,i) & """>" & ord & "</a>" exit function end if next Link=ord end function
Den lineære søgning er ok for op til 50 til 100 vil jeg tro. Kan du sortere i SQL'en hvor der ikke gøres forskel på små og store bogstaver? Ellers har jeg en meget hurtig sorteringsrutine. Jeg takker i øvrigt for point. :o)
Synes godt om
Slettet bruger
26. september 2003 - 14:21#40
tror gerne jeg vil ha din quicksort... Takker for den massive indsats :)
Det er ikke QuickSort, men CombSort. Den er næsten lige så hurtig som QuickSort, men er simplere at lave og forstå.
sub Sort(A) 'Denne procedure sorterer arrayet, som 'overføres ved reference. 'Det er metoden CombSort, der benyttes. 'Den er næsten lige så hurtig som QuickSort dim n, gap,OK,i,j,tmp 'tabellen A sorteres. CombSort n=Ubound(A) gap = n ok = True While ok If gap < 1 Then gap = 1 ok = (gap <> 1) For i = 0 To n - gap j = i + gap If A(i) > A(j) Then tmp = A(j): A(j) = A(i): A(i) = tmp ok=true End If Next gap = Int(gap / 1.33) 'Tallet 1.33 er bedst Wend end sub
For at sortere et array A skal man blot lave procedurekaldet.
Sort A
Det vil kræve lidt tilretning at få det til at virke med dit array. Derefte er det blot at lave binærsøgning istedet for den lineære søgning.
Synes godt om
Slettet bruger
26. september 2003 - 15:27#42
har ikke rigtig mod på selv at tilpasse det :( Har du?
Her er så sorteringsproceduren med et lille test-array:
Option Explicit dim arrOrd(1,6), tekst, i, txt arrOrd(0,0)="5":arrOrd(1,0)="færge" arrOrd(0,1)="1":arrOrd(1,1)="Aben" arrOrd(0,2)="7":arrOrd(1,2)="kørte" arrOrd(0,3)="6":arrOrd(1,3)="gåsefod" arrOrd(0,4)="3":arrOrd(1,4)="Cykel" arrOrd(0,5)="4":arrOrd(1,5)="drengen" arrOrd(0,6)="2":arrOrd(1,6)="bil"
sub Sort(A) 'A skal være en tabel af form A(1,n) 'tabellen A sorteres efter 2.plads. CombSort dim n, gap,OK,i,j,tmp n=Ubound(A,2) gap = n ok = True While ok If gap < 1 Then gap = 1 ok = (gap <> 1) For i = 0 To n - gap j = i + gap If A(0,i) > A(0,j) Then tmp = A(0,j): A(0,j) = A(0,i): A(0,i) = tmp tmp = A(1,j): A(1,j) = A(1,i): A(1,i) = tmp ok=true End If Next gap = Int(gap / 1.33) 'Tallet 1.33 er bedst Wend end sub
sort arrOrd 'Her er en testudskrift: for i=0 to 6 txt=txt & arrOrd(1,i) & arrOrd(0,i) & "," next msgbox txt
Sådan. Nu får du hele molevitten. Der forskellige små ændringer, så du må ikke bruge noget af det gamle. Ordtabellen bliver sorteret, og samtidig bliver alle tegn i den lavet om til små bogstaver.
tekst="En bil kom kørende. Drengen troede at han kørte på en cykel, men ville hellere køre bil, men så var det en færge" N=Ubound(arrOrd,2)
sub Sort(A) 'A skal være en tabel af form A(1,n) 'tabellen A sorteres efter 2.plads. CombSort 'alle bogstaver laves om til små bogstaver. dim n, gap,OK,i,j,tmp n=Ubound(A,2) for i=0 to n arrOrd(1,i)=Lcase(arrOrd(1,i)) next gap = n ok = True While ok If gap < 1 Then gap = 1 ok = (gap <> 1) For i = 0 To n - gap j = i + gap If A(1,i) > A(1,j) Then tmp = A(0,j): A(0,j) = A(0,i): A(0,i) = tmp tmp = A(1,j): A(1,j) = A(1,i): A(1,i) = tmp ok=true End If Next gap = Int(gap / 1.33) 'Tallet 1.33 er bedst Wend end sub
function fundet(ord,nr) dim i,j,k,tblOrd fundet=false i=0: j=N do k=(i+j)\2 tblOrd=arrOrd(1,k) if ord=tblOrd then fundet=true: nr=arrOrd(0,k) exit function elseif ord>tblOrd then i=k+1 else j=k-1 end if loop until i>j end function
function Link(ord) dim i, nr if fundet(Lcase(ord),nr) then Link="<a href=""ord.asp?id=" & nr & """>" & ord & "</a>" exit function end if Link=ord end function
function LinkTekst(tekst) dim p, ord, tmp, ch,L const Bgst="abcdefghijklmnopqrstuvvwyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" p=1: L=len(tekst) while p<=L ch=mid(tekst,p,1):p=p+1 while Instr(Bgst,ch)>0 and p<=L+1 ord=ord & ch ch=mid(tekst,p,1) p=p+1 wend if ord<>"" then tmp=tmp & Link(ord) & ch ord="" else tmp=tmp & ch end if wend LinkTekst=tmp end function
sort arrOrd 'Her er en testudskrift: MsgBox Linktekst(tekst)
Synes godt om
Slettet bruger
27. september 2003 - 14:56#47
Dit eksempel ovenfor virker fint nok - bare ikke hvis arrayet initialires
SQL = "SELECT ord, id FROM ord" Set rs = Conn.Execute(SQL) if not rs.eof then arrOrd = rs.getrows() end if rs.close set rs = nothing
Nu har du igen bytte tilbage til rækkefølgen ord, ID. Vi var da ellers blevet enige om rækkefølgen ID, ord, sådan, som jeg har lavet det i mit lille testeksempel. Så mon ikke det virker, når du laver om på din SQL-sætning.
Synes godt om
Slettet bruger
27. september 2003 - 16:20#49
Doh! Nu må jeg da lige spænde hjelmen... Det er alt det copy/paste.....
Er det et undervisningsprogram, du er ved at lave? Grammatik eller sprogindlæring?
Nu er jeg jo blevet nysgerrig.
Synes godt om
Slettet bruger
27. september 2003 - 16:33#51
Det er til et forum, hvor der skal være et fælles opslagsværk (som brugerne løbende bidrager til) og jeg formoder at ordene ofte vil indgå i teksten på de forskellige indlæg på forumet :)
Synes godt om
Slettet bruger
07. december 2003 - 16:54#52
nmh, er du her stadig? Har nemlig lidt probs med det..?
Har lige et spørgsmål til. Jeg har valgt at lave det xhtml, hvorfor jeg har lavet nedenstående funktion
function xhtml(streng) streng = replace(streng,"æ","æ") streng = replace(streng,"Æ","Æ") streng = replace(streng,"ø","ø") streng = replace(streng,"Ø","Ø") streng = replace(streng,"å","å") streng = replace(streng,"Å","Å") streng = replace(streng,"'","`") xhtml = streng end function
som konverterer danske bogstaver. Det gør at dit script ikke længere virker, hvis der indgår et af de konverterede bogstaver i ordet. Hvordan fixer vi det?
Hej igen. Jeg kigger på det i weekenden. Hvilke fordel får du ved at skifte til xhtml?
Synes godt om
Slettet bruger
30. januar 2004 - 15:58#56
Det lyder godt :) >Hvilke fordel får du ved at skifte til xhtml? Tjah - nu har jeg bare lavet det hele i xhtml, og så er det jo sjovest hvis det validerer, men angiveligt er det mere platformsuafhængigt.
Er det blot sådan, at alle forekomster af æ,ø,å og Æ,Ø,Å nu er erstattet med de "æ", .... i de tekststrenge, der behandles? Er der ikke andre ændringer?
Umiddelbart ville jeg så tro, at løsningen var at konvertere tilbage til æøå..., og så igen, når scriptet har gjort sin ting, konvertere til "æ",...
Synes godt om
Slettet bruger
30. januar 2004 - 16:11#58
Hmm,
har nu lavet en xhtml_reverse funktion men jeg udskriver jo med
Selv tak, det var så lidt. Jeg skal ikke have point for dette. Jeg har jo fået point for dette spørgsmål.
Synes godt om
Ny brugerNybegynder
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.