Om toewijzingen zoals title = "Blue = Green" te extraheren, match je de sleutel en de volledige waarde tussen aanhalingstekens samen. In deze Mac-handleiding gebruik je JavaScript in Safari om interne gelijktekens, aanhalingstekens en backslashes te behouden en ongeldige regels te melden.
Waarom gaat de waarde verloren als je splitst op gelijktekens?
Neem deze synthetische toewijzing:
title = "Blue = Green"
De bedoelde sleutel is title; de waarde, inclusief de oorspronkelijke aanhalingstekens, is "Blue = Green". Alleen het eerste gelijkteken scheidt de velden. Het tweede hoort bij de tekst tussen aanhalingstekens.
JavaScripts split("=") splitst bij elke overeenkomst zonder aanhalingstekens te interpreteren. Een limiet toevoegen, zoals in split("=", 2), kapt de resulterende array af; alles na het eerste scheidingsteken blijft daardoor niet behouden. Dit volgt uit de definitie van String.prototype.split in de standaard.
De juiste methode hangt af van de grammatica van de invoer. Gebruik deze keuzehulp voordat je de tekst wijzigt:
| Invoerconditie | Geschikte aanpak |
|---|---|
| Eén toewijzing per regel; alleen scheiden is van belang | Zoek het eerste gelijkteken en behoud de volledige rest. |
| Eén toewijzing per regel; ook de aanhalingstekens en syntaxis van de sleutel moeten worden gecontroleerd | Match de volledige regel met een gedefinieerd toewijzingspatroon, zoals hieronder. |
| Meerdere toewijzingen per regel of waarden die over meerdere regels lopen | Gebruik een parser die voor die aanvullende regels is ontworpen. |
Voor deze taak biedt validatie van de volledige regel een nuttige extra controle: een niet-afgesloten aanhalingsteken of onverwachte tekst aan het einde levert een fout op in plaats van een onvolledige extractie.
Welke grammatica voor toewijzingen behoudt dit voorbeeld?
Het onderstaande programma implementeert een bewust klein tekstformaat. Dit zijn de opgestelde regels, geen bewering dat het elke JavaScript-toewijzing kan parsen:
- Elke niet-lege regel bevat één toewijzing.
- Sleutels beginnen met een ASCII-letter of een underscore, gevolgd door ASCII-letters, cijfers of underscores.
- Waarden gebruiken bij elkaar passende rechte enkele of dubbele aanhalingstekens. Lege waarden tussen aanhalingstekens zijn geldig.
- Binnen een waarde wordt een backslash gekoppeld aan het volgende teken, behalve aan een carriage return of newline. Beide tekens blijven ongewijzigd.
- Spaties en tabs mogen om de sleutel, het scheidingsteken en de waarde staan. Spaties en tabs binnen aanhalingstekens blijven onderdeel van de waarde.
- Fysieke regeleinden mogen LF, CRLF of CR zijn. Waarden tussen aanhalingstekens kunnen niet over die regeleinden heen lopen.
- Commentaar, puntkomma's en waarden zonder aanhalingstekens vallen buiten deze grammatica.
Bijvoorbeeld: caption='Small = calm' is geldig. note="Use \"a=b\" here" is dat ook: de geëscapete dubbele aanhalingstekens horen bij de waarde. caption='Small = calm" heeft daarentegen niet-overeenkomende scheidingstekens en moet worden gecorrigeerd.
De uitvoer slaat elke waarde op als rawValue, inclusief de omringende aanhalingstekens. De extractie decodeert geen escape-sequenties: de twee tekens \n blijven twee tekens. Zo is het resultaat geschikt om toewijzingstekst te herschikken zonder de geschreven weergave te veranderen.
Dubbele sleutels blijven ook afzonderlijke items in hun oorspronkelijke volgorde. Zo wordt een eerdere waarde niet stilzwijgend vervangen wanneer dezelfde sleutel opnieuw voorkomt.
Hoe voer je de transformatie uit in Safari op een Mac?
De Web Inspector van Safari biedt een plek om JavaScript uit te voeren. Schakel deze in via Safari → Instellingen… → Geavanceerd → Toon functies voor webontwikkelaars. Kies vervolgens Ontwikkel → Toon Web Inspector, of druk op Option-Command-I. Deze stappen zijn beschreven in WebKits Web Inspector inschakelen.
Selecteer het tabblad Console en gebruik het invoerveld voor het volledige onderstaande programma. WebKit beschrijft het prompt als een invoerveld om JavaScript uit te voeren in de naslag voor de Web Inspector-interface. Het voorbeeld werkt uitsluitend op de tekst die erin is opgenomen.
Het voorbeeld gebruikt String.raw, zodat de backslashes behouden blijven tijdens het aanmaken van de JavaScript-string. Houd er bij het aanpassen van het voorbeeld rekening mee dat backticks en ${...} nog steeds betekenis hebben in een template-literal; deze invoer bevat geen van beide. Raadpleeg de documentatie over String.raw() in JavaScript voordat je die tekens toevoegt.
(() => {
const source = String.raw`title = "Blue = Green"
caption='Small = calm'
note = "Use \"a=b\" here"
marker = "$1 = $$"
empty = ""`;
const assignment = /^[ \t]*([A-Za-z_][A-Za-z0-9_]*)[ \t]*=[ \t]*("(?:\\[^\r\n]|[^"\\\r\n])*"|'(?:\\[^\r\n]|[^'\\\r\n])*')[ \t]*$/;
function extractAssignments(text) {
const pairs = [];
const errors = [];
const lines = text.split(/\r\n|\n|\r/);
lines.forEach((line, index) => {
if (/^[ \t]*$/.test(line)) return;
const match = assignment.exec(line);
if (!match || match[0].length !== line.length) {
errors.push(`Line ${index + 1}: expected key = quoted value`);
return;
}
pairs.push({ key: match[1], rawValue: match[2] });
});
if (errors.length) throw new Error(errors.join("\n"));
return pairs;
}
const pairs = extractAssignments(source);
const extracted = pairs
.map(({ key, rawValue }) => `key: ${key}\nvalue: ${rawValue}`)
.join("\n\n");
console.log(extracted);
const normalized = source.split(/\r\n|\n|\r/)
.map(line => line.replace(assignment,
(_whole, key, rawValue) => key + " = " + rawValue))
.join("\n");
console.log("Normalized assignments:\n" + normalized);
})();
Dit is een volledig programma met voorbeeldgegevens, zonder imports of extra pakketten. De omhullende functie houdt de declaraties lokaal, zodat je het hele voorbeeld na het aanpassen van de invoer opnieuw kunt uitvoeren.
De eerste consolemelding scheidt de velden:
key: title
value: "Blue = Green"
key: caption
value: 'Small = calm'
key: note
value: "Use \"a=b\" here"
key: marker
value: "$1 = $$"
key: empty
value: ""
De tweede melding toont toewijzingen met consistente spatiëring:
Normalized assignments:
title = "Blue = Green"
caption = 'Small = calm'
note = "Use \"a=b\" here"
marker = "$1 = $$"
empty = ""
Selecteer en kopieer het tekstblok dat bij de desktoptaak past. Het programma toont de resultaten via console.log, zoals WebKit beschrijft in de Console Object API. Het schrijft geen bestand.
Hoe zorgt het patroon ervoor dat gelijktekens tussen aanhalingstekens intact blijven?
Het patroon heeft twee capturegroepen: één voor de sleutel en één voor de volledige waarde tussen aanhalingstekens. De interne (?:...)-groepen ordenen alternatieven zonder extra velden vast te leggen. Dit gebruik van capturegroepen en groepen zonder vastlegging volgt de documentatie over groepen in JavaScript.
Na het matchen van de sleutel consumeert het patroon het scheidingsteken van de toewijzing eenmaal. Daarna kiest het de tak voor dubbele of enkele aanhalingstekens. Elke tak accepteert gewone tekens, waaronder gelijktekens, of een backslash gekoppeld aan het volgende teken. Een niet-geëscapet aanhalingsteken dat bij de tak past, sluit die af.
Deze structuur verwerkt geëscapete aanhalingstekens zonder ze als het einde van de waarde te behandelen. Ook paren backslashes worden verwerkt: nadat een paar samen is geconsumeerd, kan een volgend niet-geëscapet aanhalingsteken de string afsluiten. Lege waarden werken omdat de inhoud tussen aanhalingstekens nul keer mag herhalen.
Het programma leest de vastgelegde waarden via match[1] en match[2]. Een mislukte aanroep van exec() retourneert null, zoals vastgelegd in ECMAScript RegExp.prototype.exec. De aanvullende lengtevergelijking vereist dat de match de volledige fysieke regel beslaat.
Alleen spaties en tabs gelden als omringende opmaak. Het programma haalt nooit witruimte uit de binnenkant van een waarde. Daardoor behoudt label = " Blue = Green " de spaties aan beide uiteinden van de inhoud tussen aanhalingstekens.
Waarom gebruik je een vervangingsfunctie bij het herformatteren?
De normalisatiestap retourneert de vastgelegde sleutel, een gestandaardiseerd scheidingsteken en de vastgelegde waarde. De callback voor de vervanging ontvangt eerst de volledige match, gevolgd door de twee vastgelegde waarden. JavaScript beschrijft deze argumentvolgorde in String.prototype.replace().
De geretourneerde tekst van een callback wordt letterlijk ingevoegd, zonder vervangingstokens zoals $1 of $$ te interpreteren. Zo blijft de voorbeeldwaarde "$1 = $$" intact. Dezelfde documentatie licht dit verschil toe tussen vervangingsstrings en vervangingsfuncties.
Een vaste vervangingssjabloon zoals "$1 = $2" zou ook werken voor dit specifieke patroon: vastgelegde inhoud wordt ingevoegd zonder een tweede vervangingsronde. Een callback is vooral handig wanneer je vervangingstekst dynamisch samenstelt, omdat de geretourneerde waarde dan gescheiden blijft van de syntaxis van vervangingssjablonen.
De normalisatie verandert bewust de omringende spatiëring en zet fysieke regeleinden om naar LF. Lege regels en de exacte tekst tussen aanhalingstekens blijven behouden. Als de oorspronkelijke spatiëring en regeleinden nodig zijn, gebruik je de geëxtraheerde paren voor inspectie en laat je de oorspronkelijke source ongewijzigd.
Wat moet je controleren voordat je het resultaat gebruikt?
De extractiefunctie verzamelt fouten met regelnummers en genereert een fout voordat een van beide resultaten wordt afgedrukt. Lege regels die alleen spaties of tabs bevatten, worden expliciet genegeerd. Een ongeldige niet-lege regel kan daardoor niet ongemerkt verdwijnen in een ogenschijnlijk geslaagd gedeeltelijk resultaat.
Gebruik deze synthetische gevallen om onverwachte invoer te diagnosticeren:
| Toewijzingstekst | Verwacht resultaat |
|---|---|
x="a=b=c" |
Behoud de volledige waarde tussen aanhalingstekens. |
x='' |
Accepteer een lege waarde tussen enkele aanhalingstekens. |
x=" a=b " |
Behoud de spaties binnen de aanhalingstekens. |
x="a\"=b" |
Behoud het geëscapete aanhalingsteken en gelijkteken. |
x="a=b |
Meld het ontbrekende afsluitende aanhalingsteken. |
x="a" extra |
Meld de tekst aan het einde. |
x="a" y="b" |
Wijs meerdere toewijzingen op één regel af. |
x=a=b |
Wijs een waarde zonder aanhalingstekens af volgens deze grammatica. |
De extractie- en normalisatielogica van het programma is uitgevoerd in Node.js 20.19.2 met het getoonde voorbeeld. Vijftien aanvullende deterministische controles dekten gelijktekens binnen aanhalingstekens, lege waarden, geëscapete aanhalingstekens, paren backslashes, letterlijke dollartokens, ongeldige regels, dubbele sleutels en verwerking van lege regels. Daarmee is de opgestelde transformatielogica gecontroleerd; dit betekent niet dat de Safari-interface is getest.
Als een regel faalt, controleer dan eerst de scheidingstekens en zoek vervolgens naar een niet-gepaarde backslash aan het einde, tekst aan het einde of een niet-ondersteunde sleutel. Pas de grammatica bewust aan als de taak meer syntaxis vereist. Voor het beschreven formaat met één toewijzing per regel levert dit herbruikbare paar velden op, waarbij de waarde tussen aanhalingstekens alle interne gelijktekens behoudt.
Bronnen
- Web Inspector inschakelen — WebKit.
- Web Inspector-interface — WebKit.
- Console Object API — WebKit.
- ECMAScript® 2027 Language Specification — Text Processing — Ecma International / TC39, werkversie.
- String.raw() — MDN Web Docs.
- Groepen en backreferences — MDN Web Docs.
- String.prototype.replace() — MDN Web Docs.