javascript - RegExp ei toimi luetulla HTML-tiedostolla
Ensinnäkin tiedän, miten useimmat RegExp-kysymykset menevät; eikä tämä ole yksi niistä "kirjoita koodini puolestani" -kysymyksistä.
Hämmennykseni johtuu siitä, että minun RegExp toimii regexrissä ja Chromen kehittäjätyökaluissa, kun tarkastelen document.body.textContent -sisältöä, mutta ei HTML-tiedostossa sen jälkeen kun olen lukenut sen io.js:llä.
io.js on versio 1.5.1, toimii Windows 8:lla
Miksi se toimisi molemmissa luetelluissa paikoissa, mutta ei io.js:ssä? Enkö ota jotain huomioon, mitä io.js tekee tiedostojen lukemiseen?
Minun RegExp tulisi vastata "@{each ___->___} text and line breaks @{/each}" kuten alla olevassa linkissä, mutta sen sijaan se palauttaa null
Tässä on se, mitä yritän käyttää: http://regexr.com/3aldk
Säännöllinen lauseke :
/@\{each ([a-zA-Z0-9->.]*)\}([\s\S]*)@\{\/each}/gJS (Esimerkki):
fs.readFile('view.html', {encoding:'utf8'}, function(error, html) {
console.log(html.match(myRegExp)); // null
});
HTML :
<!doctype html>
<html>
<head>
<title>@{title}</title>
</head>
<body>
<h1>@{foo.bar}</h1>
<p>
Lorem ipsum dolor sit amet, @{foo.baz.hoo}
</p>
@{each people->person}
<div>
<b>@{person.name}:</b> @{person.age}
</div>
@{/each}
</body>
</html>
Puuttuuko minulta jokin ilmeinen, kuten merkki, joka on takapuolella, mutta ei ole koskaan palvellut?
Vastaus #1
Ongelma tässä piilee hienovaraisella rajalla määrityksen ja toteutusten välillä.
ECMAscript 5.1 -määritelmä sanoo, että:
Merkkiä
-voidaan käsitellä kirjaimellisesti tai se voi merkitä aluetta. Sitä käsitellään kirjaimellisesti, jos se on ClassRangesin ensimmäinen tai viimeinen merkki, alueen määrityksen alku- tai loppuraja, tai jos se seuraa välittömästi alueen määritystä.
Regular-Expressions.info huomauttaa, että:
Tavuviivat muissa sijainneissa merkkiluokissa, joissa ne eivät voi muodostaa aluetta, voidaan tulkita kirjaimina tai virheinä. Säännöllisen lausekkeen (regex) muodot ovat tässä melko epäyhtenäisiä.
Johtopäätökset :
Turvallinen tapa sisällyttää viiva - miinusmerkki merkkiluokkaan on jompikumpi seuraavista:
- pakene siitä (esim.
[a-zA-Z0-9\->.]) asettamalla se luokan ensimmäiseksi merkiksi (esim.
[-.>a-zA-Z0-9])- poikkeus: kieltoluokassa se tulee toisena, heti
^-merkin jälkeen (esim.[^-.>a-zA-Z0-9])
- poikkeus: kieltoluokassa se tulee toisena, heti
[a-zA-Z0-9.>-])Yleiset koodausohjeet suosittelevat sijoittamaan jaksot ensin ja päättämään merkkiluokan väliviivaan, tämä välttää epäselvyyksiä ja auttaa luettavuutta.
Yhteenvetona, RegExisi tulisi olla:
/@\{each ([a-zA-Z0-9>.-]*)\}([\s\S]*)@\{\/each}/g
Lisävinkkinä:
voit myös kirjoittaa uudelleen [\s\S] (mikä tahansa välilyöntimerkki tai mikä tahansa ei-välilyöntimerkki) muotoon [^] (ei mitään)
joka päätyisi sinut seuraavan RegExin kanssa:
/@\{each ([a-zA-Z0-9>.-]*)\}([^]*)@\{\/each}/g
JavaScript ... käsittelee
[^]kuin käännettyä tyhjää merkki-luokkaa, joka vastaa mitä tahansa yksittäistä merkkiä. - lähde
