title = "Blue = Green" gibi atamaları çıkarmak için anahtarı ve tırnak içindeki değerin tamamını birlikte eşleştirin. Bu Mac kılavuzu, hatalı satırları bildirirken içteki eşittir işaretlerini, tırnakları ve ters eğik çizgileri korumak için Safari’de JavaScript kullanır.

Eşittir işaretlerine göre bölmek değeri neden kaybettirir?

Şu yapay atamayı ele alalım:

title = "Blue = Green"

Amaçlanan anahtar title; özgün tırnakları da içeren değer ise "Blue = Green" şeklindedir. Alanları yalnızca ilk eşittir işareti ayırır. İkincisi tırnak içindeki metne aittir.

JavaScript’in split("=") yöntemi, tırnakları yorumlamadan her eşleşmede böler. split("=", 2) örneğindeki gibi bir sınır eklemek, sonuç dizisini kısaltır; ilk ayırıcıdan sonraki her şeyi korumaz. Bu, standardın String.prototype.split tanımı ile uyumludur.

Doğru yöntem, girdinin dilbilgisine bağlıdır. Metni değiştirmeden önce bu karar tablosunu kullanın:

Girdi koşulu Uygun yaklaşım
Her satırda bir atama var; yalnızca ayırmak önemli İlk eşittir işaretini bulup geri kalan kısmın tamamını koruyun.
Her satırda bir atama var; tırnakların ve anahtar sözdiziminin de denetlenmesi gerekiyor Aşağıdaki gibi, satırın tamamını tanımlı bir atama kalıbıyla eşleştirin.
Satır başına birden çok atama var veya değerler satırlara yayılıyor Bu ek kurallar için tasarlanmış bir ayrıştırıcı kullanın.

Bu görev için satırın tamamını doğrulamak yararlı bir ek kontrol sağlar: eşleşmeyen bir tırnak veya beklenmeyen sondaki metin, eksik bir çıkarım yerine hata üretir.

Bu örnek hangi atama dilbilgisini koruyor?

Aşağıdaki program, bilerek küçük tutulmuş bir metin biçimini uygular. Bunlar, her JavaScript atamasını ayrıştırdığı iddiası değil, programın tanımlanmış kurallarıdır:

  • Boş olmayan her satırda bir atama bulunur.
  • Anahtar ASCII harfi veya alt çizgiyle başlar; devamında ASCII harfleri, rakamlar veya alt çizgiler bulunabilir.
  • Değerler, eşleşen düz tek tırnak ya da çift tırnak kullanır. Boş tırnaklı değerlere izin verilir.
  • Değer içinde ters eğik çizgi, satır başı veya satır sonu karakteri dışında, kendisinden sonraki karakterle eşleşir. Her iki karakter de değiştirilmeden kalır.
  • Anahtarın, ayırıcının ve değerin çevresinde boşluk ve sekme bulunabilir. Tırnak içindeki boşluklar ve sekmeler değerin parçası olarak kalır.
  • Fiziksel satır sonları LF, CRLF veya CR olabilir. Tırnaklı değerler bu satır sonlarını aşamaz.
  • Yorumlar, noktalı virgüller ve tırnaksız değerler bu dilbilgisinin dışındadır.

Örneğin, caption='Small = calm' geçerlidir. note="Use \"a=b\" here" de geçerlidir: kaçışlanmış çift tırnaklar değere aittir. Buna karşılık caption='Small = calm" içindeki sınırlayıcılar eşleşmez ve düzeltilmelidir.

Çıktı, her değeri tırnakları da dahil olmak üzere rawValue biçiminde saklar. Çıkarma işlemi kaçış dizilerini çözmez: \n karakterleri iki ayrı karakter olarak kalır. Böylece sonuç, yazılı gösterimi değiştirmeden atama metnini yeniden düzenlemek için kullanılabilir.

Yinelenen anahtarlar da özgün sıraları korunarak ayrı girdiler olarak kalır. Bu tercih, aynı anahtar yeniden göründüğünde önceki değerin sessizce üzerine yazılmasını önler.

Dönüşümü Mac’te Safari kullanarak nasıl çalıştırırsınız?

Safari’nin Web Inspector’ı JavaScript değerlendirmek için bir alan sağlar. Bu özelliği Safari → Settings… → Advanced → Show features for web developers yoluyla etkinleştirin. Ardından Develop → Show Web Inspector seçeneğini belirleyin veya Option-Command-I tuşlarına basın. Bu adımlar WebKit’in Web Inspector’ı Etkinleştirme belgesinde açıklanmıştır.

Console sekmesini seçin ve aşağıdaki programın tamamını girmek için giriş istemini kullanın. WebKit, Web Inspector Arayüzü başvurusunda bu istemi JavaScript değerlendirmek için kullanılan bir giriş alanı olarak belgeler. Örnek yalnızca programın içindeki yazılmış metin üzerinde işlem yapar.

Örnekte, ters eğik çizgilerin JavaScript dizesi oluşturulurken korunması için String.raw kullanılır. Örneği düzenlerken ters tırnakların ve ${...} ifadesinin şablon dizgesi anlamı taşıdığını unutmayın; bu girdide ikisi de yoktur. Bu karakterleri eklemeden önce JavaScript String.raw() belgelerine bakın.

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

Bu, örnek veriler içeren, içe aktarma veya ek paket gerektirmeyen eksiksiz bir programdır. Çevresindeki işlev bildirimleri yerel kapsamda tutar; böylece örnek veri düzenlendikten sonra tüm örnek yeniden çalıştırılabilir.

İlk konsol mesajı alanları birbirinden ayırır:

key: title
value: "Blue = Green"

key: caption
value: 'Small = calm'

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

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

key: empty
value: ""

İkinci mesaj, aralıkları tutarlı atamalar sunar:

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

Masaüstü görevine uygun metin bloğunu seçip kopyalayın. Program sonuçları console.log üzerinden gösterir; WebKit bunu Console Object API içinde belgeler. Program dosyaya yazmaz.

Kalıp, tırnaklı eşittir işaretlerini nasıl korur?

Kalıpta iki yakalama grubu vardır: biri anahtar, diğeri tırnaklı değerin tamamı içindir. Kalıbın içindeki (?:...) grupları, ek yakalanmış alan oluşturmadan seçenekleri düzenler. Yakalama ve yakalamayan grupların bu şekilde kullanımı JavaScript grupları belgeleriyle uyumludur.

Anahtarı eşleştirdikten sonra kalıp atama ayırıcısını bir kez tüketir. Ardından çift tırnaklı veya tek tırnaklı dalı seçer. Her dal, eşittir işaretleri de dahil olmak üzere sıradan karakterleri ya da ters eğik çizgiyle eşleşen sonraki karakteri kabul eder. Kaçışlanmamış, eşleşen bir tırnak o dalı kapatır.

Bu yapı, kaçışlanmış tırnakları değerin sonu olarak algılamadan işler. Eşleşen ters eğik çizgileri de doğru işler: bir çift birlikte tüketildikten sonra gelen kaçışlanmamış bir tırnak dizgeyi kapatabilir. Tırnak içeriği sıfır kez yinelenebildiğinden boş değerler de çalışır.

Program yakalanan değerleri match[1] ve match[2] üzerinden okur. Başarısız bir exec() çağrısı, ECMAScript’in RegExp.prototype.exec tanımında belirtildiği gibi null döndürür. Ek uzunluk karşılaştırması, eşleşmenin fiziksel satırın tamamını kapsamasını şart koşar.

Çevre biçimlendirmesi olarak yalnızca boşluklar ve sekmeler kabul edilir. Program, değerin içini hiçbir zaman kırpmaz. Bu nedenle label = " Blue = Green ", tırnaklı içeriğin her iki ucundaki boşlukları da korur.

Yeniden biçimlendirirken neden bir değiştirme işlevi kullanılır?

Normalleştirme adımı, yakalanan anahtarı, standartlaştırılmış bir ayırıcıyı ve yakalanan değeri döndürür. Değiştirme geri çağrısı önce tam eşleşmeyi, ardından iki yakalamayı alır. JavaScript bu bağımsız değişken sırasını String.prototype.replace() içinde belgeler.

Geri çağrının döndürdüğü metin, $1 veya $$ gibi değiştirme belirteçleri yorumlanmadan doğrudan eklenir. Bu, "$1 = $$" örnek değerini korur. Aynı belgeler, değiştirme dizeleriyle değiştirme işlevleri arasındaki bu farkı açıklar.

"$1 = $2" gibi sabit bir değiştirme şablonu da bu özel kalıp için işe yarardı: yakalanan içerikler ikinci bir değiştirme turu olmadan eklenir. Geri çağrı, değiştirme metnini dinamik olarak oluştururken özellikle kullanışlıdır; çünkü döndürülen değeri değiştirme şablonunun sözdiziminden ayrı tutar.

Normalleştirme, çevredeki boşlukları kasıtlı olarak değiştirir ve fiziksel satır sonlarını LF’ye dönüştürür. Boş satırları ve tırnak içindeki metnin aynısını korur. Görev özgün boşlukları ve satır sonlarını gerektiriyorsa, çıkarılan çiftleri inceleme için kullanın ve özgün source değerini değiştirmeden bırakın.

Sonucu kullanmadan önce neleri kontrol etmelisiniz?

Çıkarma işlevi satır numaralı hataları toplar ve herhangi bir sonuç yazdırılmadan önce hata fırlatır. Yalnızca boşluk veya sekme içeren boş satırlar açıkça yok sayılır. Böylece biçimi bozuk, boş olmayan bir satır görünüşte başarılı olan kısmi bir sonucun içine gizlenemez.

Beklenmeyen girdileri tanılamak için şu yapay örnekleri kullanın:

Atama metni Beklenen sonuç
x="a=b=c" Tırnaklı değerin tamamını koruyun.
x='' Boş tek tırnaklı değeri kabul edin.
x=" a=b " Tırnak içindeki boşlukları koruyun.
x="a\"=b" Kaçışlanmış tırnağı ve eşittir işaretini koruyun.
x="a=b Eksik kapanış tırnağını bildirin.
x="a" extra Sondaki metni bildirin.
x="a" y="b" Tek satırdaki birden çok atamayı reddedin.
x=a=b Bu dilbilgisi uyarınca tırnaksız değeri reddedin.

Programın çıkarma ve normalleştirme mantığı, gösterilen örnekle Node.js 20.19.2’de çalıştırıldı. On beş ek deterministik kontrol; tırnaklı eşittir işaretlerini, boş değerleri, kaçışlanmış tırnakları, eşleşen ters eğik çizgileri, düz dolar belirteçlerini, biçimi bozuk satırları, yinelenen anahtarları ve boş satırların işlenmesini kapsadı. Bu, tanımlanmış dönüşüm mantığını doğrular; Safari arayüzünün denendiği anlamına gelmez.

Bir satır başarısız olursa önce sınırlayıcıları kontrol edin; ardından eşleşmeyen son bir ters eğik çizgi, sondaki metin veya desteklenmeyen bir anahtar olup olmadığına bakın. Görev daha fazla sözdizimi gerektiriyorsa dilbilgisini bilinçli biçimde değiştirin. Belirtilen, satır başına tek atamalı biçimde sonuç; tüm iç eşittir işaretlerini koruyan, yeniden kullanılabilir bir alan çiftidir.

Kaynaklar