WORDS
Escape-tecken: Javascript
Escapning i Javascript liknar den i JSON, men Javascript har många fler situationer där något måste - eller kan - escapas.
Strängar
I Javascript kan man ange vanliga strängar antingen med citattecken (dubbelfnuttar) eller apostrofer (enkelfnuttar). Dessa fungerar likadant, förutom att man i strängar med citattecken måste escapa eventuella citattecken, men inte behöver escapa apostrofer. Det omvända gäller strängar med apostrofer.
"Five o'clock" // Ger: Five o'clock
"Five o\'clock" // Ger: Five o'clock
'Five o\'clock' // Ger: Five o'clock
'Five o'clock' // SyntaxError
Mallsträngar
Modern Javascript stödjer interpolerade strängar (mallsträngar, template literals). Dom har många funktioner, men dom viktigaste är att kunna inkludera radbrytningar direkt, och att kunna inkludera variabler och andra uttryck direkt i en sträng. Mallsträngen omges med tecknet grav accent (backtick, `
), och för att interpolera använder man ${}
.
const name = "Dan";
console.log(`Hej ${name}!`); // Ger: Hej Dan!
Om man vill inkludera teckensekvensen ${
i sin mallsträng, måste man alltså escapa antingen $
eller {
.
`Hej \${name}!` // Ger: Hej ${name}!
`Hej \$\{name}!` // Ger: Hej ${name}!
`Hej $\{name}!` // Ger: Hej ${name}!
Regex
Reguljära uttryck (regex, regular expressions) är mycket komplicerade och kan kräva avancerad escapning. Riktigt många tecken har särskilda betydelser, och exakt vilka man behöver escapa beror på kontexten. Javacript som språk stödjer särskild syntax för regex: man skapar en regex-literal genom att omge uttrycket med snedstreck (/
). Ett enkelt regex för att matcha kapitelnummer är /Kapitel (\d+)/
.
Följande tecken har särskild betydelse: .
, *
, +
, ?
, -
, ^
, $
, {
, }
, (
, )
, |
, [
, ]
, \
. Om man anger en regex-literal (alltså omgiven med /
) så måste också /
escapas.
Teckenklasser
Det enklaste är att alltid escapa dessa tecken. Men... det kan ju hända att man inte vill skriva fler tecken än nödvändigt. Man är ju lat. Och det finns åtminstone ett sammanhang där man kan komma undan med att inte escapa så mycket: teckenklasser. En teckenklass i ett regex är när man matchar en uppsättning tecken, t.ex. alla bokstäver från a-z.
// Matchar strängar som börjar med en bokstav mellan a och z.
/^[a-z]/
// Matchar strängar som *inte* slutar med 1 eller 4.
/[^14]$/
Mellan hakparenteserna måste man inte escapa så många tecken, så /[.]/
och /[\.]/
är ekvivalenta. Man måste inte ens escapa /
, så detta är okej /[/]/
. Man måste escapa följande tecken inuti en teckenklass:
\
- alltid]
- alltid (observera att man inte måste escapa[
inuti teckenklasser; utanför teckenklasser behöver faktiskt inte]
escapas)-
- när det varken är första tecken efter[
eller sista tecken före]
(för i ändposition kan det ju inte vara ett intervall)^
- endast som första tecken, för det är ju bara då det kan negera teckenklassen
Regex och sträng
Ibland måste man kombinera regex-escapning med sträng-escapning. Detta gäller exempelvis om man behöver inkludera input i sitt regex.
function containsGreeting(string, name) {
// Escapa namnet, utifall att det skulle innehålla specialtecken.
const escapedName = escapeRegExp(name);
// \b matchar början eller slutet på ett ord. Eftersom \b har en
// annan betydelse i vanliga strängar, så måste vi escapa \.
// Det blir alltså \\b.
const re = new RegExp(`\\b(hej|hallå) ${escapedName}\\b`, "i");
return re.test(string);
}
function escapeRegExp(string) {
// $& betyder hela den matchade strängen.
return string.replace(/[-.*+?^${}()|[\]\\]/g, "\\$&");
}
Om man faktiskt vill matcha ett \
i sitt regex, så krävs så dubbel escapning:
/\\/ // Matchar strängar som innehåller *ett* \
new RegExp("\\\\") // Matchar strängar som innehåller *ett* \
Variabelnamn
Javascript stödjer många tecken som del av ett variabelnamn, också t.ex. åäö. För att tillåta sådana variabelnamn också i en ASCII-fil, så kan alla identifierare (identifiers) escapas. Detta är naturligtvis en fruktansvärd idé.
const förnamn = "Dan";
console.log("Hej " + f\u00f6rnamn); // Hej Dan
Som del av HTML
Om ditt Javascript är en del av en <script>
-tagg i HTML, så finns särskilda krav. HTML-standarden säger att ett skript avslutas omedelbart om strängen </script>
förekommer, så om man vill.
<script>
// Syntaxfel, för skriptet avslutas alltför tidigt och tolkas som:
// console.log("
console.log("</script>");
</script>
<script>
// Bättre:
console.log("<\/script>");
</script>
<script>
// Det får inte ens finnas i en kommentar: </script>
</script>