[JS+Regexp] zoek woord buiten tags

Pagina: 1
Acties:

  • js303
  • Registratie: April 2003
  • Laatst online: 22-11 12:35
hallo, mijn regexp werkt bijna goed maar nog niet 100%.
bedoeling is dat in myText een foutgespeld woord vervangen wordt door het juiste woord (die heeft de gebruiker gekozen uit een lijst). fout woord is in onderstaand voorbeeld "dus" en het te vervangen woord is "Dis".

wat de regexp moet doen is alle voorkomende "dus"-woorden in myText vervangen, maar alleen als die niet binnen een <tag> vallen. hij vervangt netjes de eerste en laatste "dus" en laat "dus" binnen de <span> tag met rust. echter het woord dus tussen de <span> open- en sluit-tag vervangt hij ook niet maar dat moet wel.

inhoud van myText:
the word dus is <span title='vervang dus niet'>dus</span> not an english word. dus, not!
code:
1
2
3
4
5
6
7
myWord = "dus";
myReplace = "Dis";
spacers = "\\s\\.\\,\\?\\!\\:\\;";
myText = myText.replace(
  /(?!<.*?)(["+spacers+">]+)("+word+")(["+spacers+"<]+)(?![^<>]*?>)/ig, 
  "$1"+myReplace+"$3"
);


iemand enig idee wat ik fout doe??

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 13:26

crisp

Devver

Pixelated

js303 schreef op woensdag 14 februari 2007 @ 20:18:
iemand enig idee wat ik fout doe??
Dit soort problemen moet je niet proberen op te lossen met een enkele regular expressie. Je zal de inhoud moeten parsen of in ieder geval tokenisen om te bepalen wat tags zijn en wat text is.

Intentionally left blank


  • js303
  • Registratie: April 2003
  • Laatst online: 22-11 12:35
OK ik ben een n00b op dat gebied maar wat is tokenisen, en wat betreft het parsen, zodra ik de HTML parse, bedoel je dan daarmee dat ik via bijv. DOM de text-elementen opzoek?

als ik je goed begrijp zou ik eerst de tekst-string moeten opdelen in losse woorden (het tokenizen), om die vervolgens te doorlopen?

[ Voor 29% gewijzigd door js303 op 15-02-2007 14:13 ]


  • js303
  • Registratie: April 2003
  • Laatst online: 22-11 12:35
ik heb nu een werkende workaround waarbij ik de brontekst / string ophak in losse woorden, scheidingstekens en tags. vervolgens wandel ik door de woorden heen en vervang waar nodig. daarna lijm ik alles weer aan elkaar... zie hieronder.

wat ik wel apart vind is dat ik een soortgelijke / nettere / standaard oplossing niet kan vinden op het web (behalve dan wat regexp-based woorden-splitters maar die handelen tags dan weer niet goed af), dit probleem moet toch vaker behandeld zijn? wellicht dat ik op de verkeerde termen g**gle... :?

input:
"my,name is <span style='color:red;'>Joe</span>!"

output:
array(
  "my"
  ","
  "name"
  " "
  "is"
  " "
  "<span style='color:red;'>"
  "Joe"
  "</span>"
  "!"
)


functie die array met losse woorden retourneert (met behoud van tags):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function ced_text2words(str) {

    var sepPos, tagOpenPos, tagClosePos;
    var regSep = /[\r\n\s\.\,\?\!\:\;]/;    // zoek scheidingstekens: \s \r \n , . ! ? : ;
    var words = new Array();                // lijst waarin woorden en scheidingstekens komen

    while (sepPos != -1 && str.length>0) {

        // check positie van eerstvolgende < tag
        tagOpenPos = str.indexOf("<");

        // check positie van eerstvolgende spatie/seperator
        sepPos = str.search(regSep);

        if (sepPos == -1) {
            // geen verdere spatie gevonden: voeg rest-string toe aan lijst en breek af
            words[words.length] = str;
            break;
        } else {
            // spatie gevonden: check of <-teken eerder dan spatie komt

            if (tagOpenPos != -1 && tagOpenPos < sepPos) {
                // indien < tag gevonden en die is eerder dan scheidingsteken:
                // 1. voeg woord tot aan <-teken toe aan woordenlijst
                // 2. zoek op >-teken
                // 3. voeg string van < t/m > of einde string toe aan woordenlijst

                if (tagOpenPos>0) words[words.length] = str.substr(0,tagOpenPos);   // 1. voeg tekst tot aan <-teken toe

                str = str.substr(tagOpenPos);

                tagClosePos = str.indexOf(">"); // 2. zoek op >-teken
                if (tagClosePos != -1) {
                    words[words.length] = str.substr(0,tagClosePos+1);  // 3a. voeg tekst van < t/m > toe
                    str = str.substr(tagClosePos+1);
                } else {
                    words[words.length] = str;  // 3b. voeg tekst van < tot einde toe
                    str = "";
                }

            } else {
                // tekst gevonden
                if (sepPos>0) words[words.length] = str.substr(0,sepPos);   // voeg tekst tot aan scheidingsteken toe
                words[words.length] = str.substr(sepPos,1); // voeg scheidingsteken zelf toe
                str = str.substr(sepPos+1);
            }
        }
    }

    return words;
}