Untuk mengekstrak tugasan seperti title = "Blue = Green", padankan kunci dan keseluruhan nilai berpetik bersama-sama. Panduan Mac ini menggunakan JavaScript dalam Safari untuk mengekalkan tanda sama, tanda petik dan garis miring songsang di dalam nilai sambil melaporkan baris yang cacat.

Mengapakah memisahkan pada tanda sama menyebabkan nilai hilang?

Pertimbangkan tugasan sintetik ini:

title = "Blue = Green"

Kunci yang dimaksudkan ialah title; nilainya, termasuk tanda petik asalnya, ialah "Blue = Green". Hanya tanda sama yang pertama memisahkan medan. Tanda sama yang kedua ialah sebahagian daripada teks berpetik.

split("=") JavaScript membahagikan teks pada setiap kemunculan tanpa mentafsir tanda petik. Menambah had, seperti dalam split("=", 2), memotong tatasusunan yang terhasil; ia tidak mengekalkan segala-galanya selepas pemisah pertama. Hal ini mengikut takrif String.prototype.split dalam piawaian.

Kaedah yang tepat bergantung pada tatabahasa input. Gunakan panduan keputusan ini sebelum mengubah teks:

Keadaan input Pendekatan yang sesuai
Satu tugasan setiap baris; pemisahan sahaja diperlukan Cari tanda sama yang pertama dan kekalkan seluruh baki teks.
Satu tugasan setiap baris; tanda petik dan sintaks kunci juga perlu disemak Padankan seluruh baris dengan corak tugasan yang ditakrifkan, seperti di bawah.
Beberapa tugasan setiap baris atau nilai merentasi beberapa baris Gunakan penghurai yang direka untuk peraturan tambahan tersebut.

Untuk tugasan ini, pengesahan seluruh baris memberikan semakan tambahan yang berguna: tanda petik yang tidak berpadanan atau teks tambahan yang tidak dijangka akan menghasilkan ralat, bukannya pengekstrakan yang tidak lengkap.

Tatabahasa tugasan apakah yang dikekalkan oleh contoh ini?

Program di bawah melaksanakan format teks yang sengaja dibuat kecil. Ini ialah peraturan yang ditetapkan, bukannya dakwaan bahawa program ini menghuraikan setiap tugasan JavaScript:

  • Setiap baris yang tidak kosong mengandungi satu tugasan.
  • Kunci bermula dengan huruf ASCII atau garis bawah, diikuti huruf ASCII, digit atau garis bawah.
  • Nilai menggunakan tanda petik tunggal lurus atau tanda petik berganda lurus yang sepadan. Nilai berpetik kosong adalah sah.
  • Dalam nilai, garis miring songsang dipasangkan dengan aksara seterusnya, kecuali aksara pulangan pengangkutan atau baris baharu. Kedua-dua aksara kekal tanpa perubahan.
  • Ruang dan tab boleh mengelilingi kunci, pemisah dan nilai. Ruang dan tab di dalam tanda petik kekal sebagai sebahagian daripada nilai.
  • Penghujung baris fizikal boleh berupa LF, CRLF atau CR. Nilai berpetik tidak boleh merentasi penghujung baris tersebut.
  • Komen, koma bertitik dan nilai tanpa tanda petik tidak termasuk dalam tatabahasa ini.

Sebagai contoh, caption='Small = calm' adalah sah. Begitu juga note="Use \"a=b\" here": tanda petik berganda yang dilepaskan ialah sebahagian daripada nilai. Sebaliknya, caption='Small = calm" mempunyai pembatas yang tidak sepadan dan perlu dibetulkan.

Output menyimpan setiap nilai sebagai rawValue, termasuk tanda petik yang mengapitnya. Pengekstrakan tidak menyahkod jujukan pelepasan: dua aksara \n kekal sebagai dua aksara. Ini menjadikan hasilnya sesuai untuk menyusun semula teks tugasan tanpa mengubah perwakilan bertulisnya.

Kunci pendua juga kekal sebagai entri berasingan dalam susunan asalnya. Pilihan itu mengelakkan nilai terdahulu digantikan secara senyap apabila kunci yang sama muncul semula.

Bagaimanakah anda menjalankan transformasi ini dalam Safari pada Mac?

Web Inspector Safari menyediakan tempat untuk menilai JavaScript. Aktifkannya melalui Safari → Settings… → Advanced → Show features for web developers. Kemudian pilih Develop → Show Web Inspector, atau tekan Option-Command-I. Langkah-langkah ini didokumenkan dalam Mengaktifkan Web Inspector oleh WebKit.

Pilih tab Console dan gunakan gesaan inputnya untuk program lengkap di bawah. WebKit mendokumenkan gesaan itu sebagai medan input untuk menilai JavaScript dalam rujukan Antara Muka Web Inspector. Contoh ini hanya beroperasi pada rentetan yang ditetapkan di dalam program.

Contoh ini menggunakan String.raw supaya garis miring songsang kekal semasa pembinaan rentetan JavaScript. Apabila mengedit contoh, ingat bahawa tanda petik belakang dan ${...} masih mempunyai makna dalam literal templat; input ini tidak mengandungi kedua-duanya. Rujuk dokumentasi JavaScript String.raw() sebelum menambah aksara tersebut.

(() => {
  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);
})();

Ini ialah program lengkap dengan data contoh dan tanpa import atau pakej tambahan. Fungsi pembungkusnya memastikan pengisytiharan kekal setempat, jadi keseluruhan contoh boleh dijalankan semula selepas sampel diedit.

Mesej konsol pertama memisahkan medan:

key: title
value: "Blue = Green"

key: caption
value: 'Small = calm'

key: note
value: "Use \"a=b\" here"

key: marker
value: "$1 = $$"

key: empty
value: ""

Mesej kedua memberikan tugasan dengan jarak yang konsisten:

Normalized assignments:
title = "Blue = Green"
caption = 'Small = calm'
note = "Use \"a=b\" here"
marker = "$1 = $$"
empty = ""

Pilih dan salin blok teks yang sesuai untuk tugasan desktop anda. Program ini memaparkan hasil melalui console.log, yang didokumenkan oleh WebKit dalam API Objek Console. Program ini tidak menulis fail.

Bagaimanakah corak ini mengekalkan tanda sama dalam nilai berpetik?

Corak ini mempunyai dua kumpulan tangkapan: satu untuk kunci dan satu lagi untuk keseluruhan nilai berpetik. (?:...) dalaman menyusun alternatif tanpa menghasilkan medan tangkapan tambahan. Penggunaan kumpulan tangkapan dan bukan tangkapan ini mengikut dokumentasi kumpulan JavaScript.

Selepas memadankan kunci, corak itu menggunakan pemisah tugasan sekali. Kemudian corak memilih sama ada cabang bertanda petik berganda atau cabang bertanda petik tunggal. Setiap cabang menerima aksara biasa—termasuk tanda sama—atau garis miring songsang yang dipasangkan dengan aksara berikutnya. Tanda petik sepadan yang tidak dilepaskan menutup cabang tersebut.

Struktur ini mengendalikan tanda petik yang dilepaskan tanpa menganggapnya sebagai penghujung nilai. Struktur ini juga mengendalikan pasangan garis miring songsang: selepas satu pasangan digunakan bersama-sama, tanda petik berikutnya yang tidak dilepaskan boleh menutup rentetan. Nilai kosong berfungsi kerana kandungan berpetik boleh berulang sifar kali.

Program membaca tangkapan melalui match[1] dan match[2]. Panggilan exec() yang gagal mengembalikan null, seperti yang dinyatakan dalam ECMAScript RegExp.prototype.exec. Perbandingan panjang tambahan memastikan padanan meliputi seluruh baris fizikal.

Hanya ruang dan tab dikira sebagai pemformatan sekeliling. Program ini tidak pernah memangkas bahagian dalam nilai. Oleh itu, label = " Blue = Green " mengekalkan kedua-dua ruang pada setiap hujung kandungan berpetik.

Mengapakah menggunakan fungsi penggantian apabila memformat semula?

Langkah penyeragaman mengembalikan kunci yang ditangkap, pemisah piawai dan nilai yang ditangkap. Panggilan balik penggantian menerima padanan lengkap dahulu, diikuti dua tangkapan. JavaScript mendokumenkan susunan argumen ini dalam String.prototype.replace().

Teks yang dikembalikan oleh panggilan balik dimasukkan secara literal, tanpa mentafsir token penggantian seperti $1 atau $$. Ini mengekalkan nilai sampel "$1 = $$" tanpa perubahan. Dokumentasi yang sama menerangkan perbezaan ini antara rentetan penggantian dengan fungsi penggantian.

Templat penggantian tetap seperti "$1 = $2" juga berfungsi untuk corak khusus ini: kandungan yang ditangkap dimasukkan tanpa laluan penggantian kedua. Panggilan balik amat berguna apabila membina teks penggantian secara dinamik kerana nilai yang dikembalikan kekal terpisah daripada sintaks templat penggantian.

Penyeragaman sengaja mengubah jarak sekeliling dan menukar penghujung baris fizikal kepada LF. Langkah ini mengekalkan baris kosong dan teks nilai berpetik yang tepat. Jika tugasan memerlukan jarak dan penghujung baris asal, gunakan pasangan yang diekstrak untuk pemeriksaan dan kekalkan source asal tanpa perubahan.

Apakah yang perlu disemak sebelum menggunakan hasilnya?

Fungsi pengekstrakan mengumpulkan ralat bernombor baris dan melontarkan ralat sebelum mana-mana hasil dipaparkan. Baris kosong yang hanya mengandungi ruang atau tab diabaikan secara jelas. Oleh itu, baris yang cacat tidak boleh hilang dalam hasil separa yang kelihatan seperti berjaya.

Gunakan kes sintetik ini untuk mendiagnosis input yang tidak dijangka:

Teks tugasan Hasil yang dijangka
x="a=b=c" Kekalkan seluruh nilai berpetik.
x='' Terima nilai kosong bertanda petik tunggal.
x=" a=b " Kekalkan ruang di dalam tanda petik.
x="a\"=b" Kekalkan tanda petik yang dilepaskan dan tanda sama.
x="a=b Laporkan tanda petik penutup yang tiada.
x="a" extra Laporkan teks tambahan di hujung.
x="a" y="b" Tolak beberapa tugasan pada satu baris.
x=a=b Tolak nilai tanpa tanda petik mengikut tatabahasa ini.

Logik pengekstrakan dan penyeragaman program ini telah dijalankan dalam Node.js 20.19.2 dengan sampel yang ditunjukkan. Lima belas semakan deterministik tambahan meliputi tanda sama dalam nilai berpetik, nilai kosong, tanda petik yang dilepaskan, pasangan garis miring songsang, token dolar literal, baris cacat, kunci pendua dan pengendalian baris kosong. Ini mengesahkan logik transformasi yang ditetapkan; ia bukan dakwaan bahawa antara muka Safari telah diuji.

Jika baris gagal, semak dahulu pembatasnya, kemudian cari garis miring songsang tunggal di hujung, teks tambahan atau kunci yang tidak disokong. Ubah tatabahasa dengan sengaja apabila tugasan memerlukan sintaks tambahan. Untuk format yang dinyatakan dengan satu tugasan setiap baris, hasilnya ialah sepasang medan boleh guna semula yang nilainya berpetik mengekalkan setiap tanda sama di dalamnya.

Sumber