Avatar billede per1291 Nybegynder
24. august 2005 - 02:49 Der er 21 kommentarer og
1 løsning

100 spørgsmål om RegExp

Hej -
Jeg har kigget på en række eksperten-spørgsmål om emnet RegExp.
Et af spørgsmålene handler om, hvordan man ser, om en indtastet tekst indeholder et HTML-link.

Eksempel på en indtastning:
<a href='http://www.noget.dk' target='_blank' onclick='bla()'>BlaBlaBla</A>

Løsningen skulle være dette java script:

function checkStr(str) {
    var re = new RegExp("<A href='([^']*)' target='([^']*)' onclick='([^>]*)'>([^<]*)<\/A>","ig");
    re.exec(str);
    return {"adr":RegExp.$1, "targ":RegExp.$2, "clck":RegExp.$3, "txt":RegExp.$4};
}
var res = checkStr(Inputtekst);
alert(res.adr);
alert(res.targ);
alert(res.txt);
alert(res.clck);

Løsningen er flot - og den virker, forudsat brugeren har benyttet enkelt-citationstegn samt præcis de tre elementer href, target og onclick, og præcis i den rækkefølge...

Lige nu vil jeg gerne vide: Kan jeg vha RegExp tage højde for, at rækkefølgen af disse indtastninger måske er forskellig?

Jeg forestiller mig at man kan navngive en gruppe elementer... - Hilsen Per
Avatar billede olebole Juniormester
24. august 2005 - 06:13 #1
<ole>

En mulighed kunne være denne funktion, der returnerer et objekt af lowercase attributter:

function checkStr(str) {
    var re = new RegExp("<A ([^>]*)>([^<]*)<\/A>","ig");
    var aAttr, oRet = {};
    re.exec(str);
    aAttr = RegExp.$1.split(" ");
    for (var i=0; i<aAttr.length; i++) {
        aTmp = aAttr[i].split("=");
        oRet[aTmp[0].toLowerCase()] = aTmp[1].replace(/\'|\"/g, "");
    }
    return oRet;
}

/mvh
</bole>
Avatar billede olebole Juniormester
24. august 2005 - 06:15 #2
- attribut-navnene er i lowercase ... værdierne er naturligvis urørte  :)
Avatar billede Slettet bruger
24. august 2005 - 08:04 #3
Kan man ikke afslutte sin expression med /i i javascript, for at den ikke er case sensitive?
Avatar billede nielle Nybegynder
24. august 2005 - 08:59 #4
Oles eksempel er lige det der skal til, men der er plads til et par enkelte forbedringer:

function checkStr(str)
{
    var re = new RegExp("<a\s+([^>]*?)\s*>[^<]*<\/a>", "ig");
    var aAttr, oRet = {};
    re.exec(str);
    aAttr = RegExp.$1.split(/\s+/);
    for (var i=0; i<aAttr.length; i++)
    {
        aTmp = aAttr[i].split(/\s*=\s*/);
        oRet[aTmp[0].toLowerCase()] = aTmp[1].replace(/\'|\"/g, "");
    }
    return oRet;
}

Disse rettelser går primært ud på at sikre imod at sikre imod at man har brugt mere end enkelt-mellemrum i url'et – dækker i øverigt også de tilfælde hvor et url er fordelt over mere end en linje. Desuden er der fjernet en enkelt parentes i RegExp'en – når $2 alligevel ikke bruges er der ingen grund til at gemme den.

wicez> Matchningen er allerede case-insensitiv (det afsluttende "ig" i RegExp'en). Det Ole gør et at forvandle alle mulige variationer på hvordan target eller TARGET skrives til at være ”target” med små bogstaver. Det gør det noget nemmere at bruge arrayet senere.
Avatar billede per1291 Nybegynder
24. august 2005 - 11:15 #5
olebole -> Det ser godt ud. Jeg er slet ikke fortrolig med det at man kan have mere end én returværdi fra en javascriptfunktion.

Dette er ikke et tillægsspørgsmål, blot en observation: Måske bør man slet ikke checke hvad der står imellem <a> og </a> - tag'ene. Nemlig fordi det er tilladt at skrive:

start<a target="xxx" hrEf="xxx" ><b>xxx</b></a>slut

nielle -> Fjernelse af mellemrum er nødvendigt, når det skal bruges i det virkelige liv, så tak for dét tip.

Læg venligst svar begge to. - Hilsen Per
Avatar billede roenving Novice
24. august 2005 - 11:21 #6
-- hvis du skal undgå problemer med tags i a-tags, kan du gå to veje, enten, som du selv er inde på, undlade at checke på nogensomhelst led, hvad der er imellem, ell også helt undlade at checke efter a-åbnetagget:

    var re = new RegExp("<a\s+([^>]*?)\s*>.*?<\/a>", "ig");

    var re = new RegExp("<a\s+([^>]*?)\s*>", "ig");
Avatar billede roenving Novice
24. august 2005 - 11:24 #7
Hov, nielle kom da vist et mellemrum for meget i udtrykket, for hvis man terminerer en søgning med '>', giver det jo ingen mening at have et mellemrum med !-)

var re = new RegExp("<a\s+([^>]*?)>", "ig");
Avatar billede nielle Nybegynder
24. august 2005 - 12:30 #8
Jeg står ved det afsluttende mellemrum (eller retter sagt det ”afsluttende whitespace”):

var re = new RegExp("<a\s+([^>]*?)\s*>", "ig");

Godt nok vil det sikkert aldrig komme i spil, men man kan jo faktisk godt forestille sig et a-tag som f.eks. er formateret på denne måde:

<a href="href://www.eksperten.dk
target="_blank"
onClick="validateForm()"
>

(og nej tak til point på denne her :^)
Avatar billede roenving Novice
24. august 2005 - 12:42 #9
-- nej, man kan ikke forestille sig et whitespace efter den sidste karakter, som ikke er > !-)
Avatar billede nielle Nybegynder
24. august 2005 - 12:49 #10
Er dette da ulovligt html, eller hvad?

<a href="http://www.eksperten.dk"
target="_blank"
onClick="validateForm()"
>Eksperten</a>
Avatar billede roenving Novice
24. august 2005 - 12:53 #11
Læs RegExp'en ordentligt !-)

Der står: find tegnfølgen <a\s+ og opret derefter en gruppe med alle tegn, indtil der kommer en > ...

-- hvis alle tegn indtil der kommer en > skal med, vil det næste tegn selvfølgelig være > !o]
Avatar billede nielle Nybegynder
24. august 2005 - 13:00 #12
Korrekt, men min regesp nøjes med at matche på alt - men at ekskludere både indledende og afsluttende whitespaces. Hvis man ikke gør dette, kan man senere få nogle mindre problemer når man laver sin første split.
Avatar billede roenving Novice
24. august 2005 - 13:06 #13
*lol*

Tag døren til venstre efter den sidste dør på venstre hånd !-)
Avatar billede per1291 Nybegynder
24. august 2005 - 13:19 #14
nielle -> Såvidt jeg forstår diskussionen, så har roenving vist ret: Du HAR allerede taget højde for whitespace førend ">", nemlig inden i de firkantede parenteser.

Men tak for din hjælp. Ærgerligt at du ikke vil have point. - Hilsen Per
Avatar billede nielle Nybegynder
24. august 2005 - 13:26 #15
Mønsteret ([^>]*?) har et lille magisk spørgsmålstegn, som gør at den ikke er grådig (det landes lazy matching). Hvis den derfor kan få lov til at matche *mindre* end det højst nødvendige så vil den gøre dette.

Uden det efterfølgende \s* i ([^>]*?)\s*> så ville matchingen - lazy matching eller ej - være tvunget til at matche alle tegn hen til >'tegnet. Men nu giver jeg den altså et \s*, hvilket har den konsekvens at den kun bliver nødt til at matche alle tegn indtil at den møder den (eventuelle) afsluttende sekvens af whitespace-tegn (herunder mellemrum og linjeskift) lige før >-tegnet.
Avatar billede per1291 Nybegynder
25. august 2005 - 00:27 #16
Nu kan jeg se hvad du mener: Ganske vist matcher det samlede udtryk i begge versioner, altså både med og uden \s* - men den RUNDE parentes skal jo bruges senere, nemlig i linjen
aAttr = RegExp.$1.split(/\s+/);
Hilsen Per
Avatar billede per1291 Nybegynder
25. august 2005 - 23:13 #17
Pokkers, ingen vil have point. Nå, men så har jeg da råd til et nyt spørgsmål. Tak til alle. - Hilsen Per
Avatar billede nielle Nybegynder
26. august 2005 - 08:00 #18
Du skulle måske lige have spurgt om der var nogen ville have point ;^)

Det er kun mig som indtil videre har sagt at jeg ikke ville have point - og det var primært fordi at jeg jo bare pudsede lidt af på Oles kode.
Avatar billede Slettet bruger
26. august 2005 - 14:37 #19
Roenving har også givet rimelig god gas i det her spg ;o)
Avatar billede per1291 Nybegynder
26. august 2005 - 17:11 #20
Beklager, fodfejl. Ole plejer ikke at nøle i halvandet døgn efter at jeg tilbyder point. roenving svarede på et spørgsmål, jeg ikke havde stillet. nielle har givet en meget nyttig forklaring EFTER at have afvist point. Der er ikke tvivl om, at I alle tre har bidraget til en bedre forståelse af emnet, og jeg vil gerne give jer point.

Jeg opretter lige et spørgsmål med point til Ole, Rønving og nielle.
Hilsen Per
Avatar billede serverservice Praktikant
26. august 2005 - 20:34 #21
->olebole jeg har ikke hørt fra dig ang. hardwarekast imorgen - der er en tur til Tvbyen , skal du med ? Dennis
http://www.hardwarekast.dannyboyd.dk/
sorry for spam
Avatar billede olebole Juniormester
26. august 2005 - 22:15 #22
*LooOooL* nu er jeg ikke helt klar over, hvem der skal undskylde for spam og hvor. Al kommunikation om 'stævnet' - på nær en enkelt mail - har GMail venligt hjulpet ned i spamskuffen. Jeg smider dig lige en mail  ;o)
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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