Peningkatan String

Raw string literal, Split, dan culture pada pembandingan string.

Daftar isi

Topik ini membahas tiga peningkatan pekerjaan string yang saling melengkapi, yaitu raw string literal dari C# 11 untuk teks berbaris yang terbaca apa adanya, opsi modern metode Split untuk memecah teks, serta pengaruh culture pada pembandingan string. Culture adalah kumpulan aturan bahasa dan wilayah, seperti aturan huruf besar dan kecil, yang memengaruhi operasi teks. Setelah topik ini diselesaikan, teks berbaris dapat ditulis tanpa tanda kutip yang perlu di-escape, pemecahan teks dapat dibersihkan sekaligus, dan pembandingan string dapat dilakukan dengan sadar terhadap culture.

Raw string literal#

Raw string literal diapit minimal tiga tanda kutip ganda """ dan isinya diambil persis sebagaimana tertulis. Tanda kutip tunggal dan garis miring terbalik di dalamnya tidak perlu di-escape, sehingga JSON, XML, dan jalur berkas ditulis seperti aslinya tanpa tanda tambahan. Bentuk ini melengkapi interpolasi $"..." dan string verbatim @"..." yang sudah dijumpai pada topik string, dan keduanya tetap sah untuk kasus masing-masing.

csharp Program.cs
// Program: raw string literal untuk JSON dan laporan berbaris.
string json = """
{
    "judul": "Aplikasi Catatan",
    "jumlahCatatan": 3,
    "kataKunci": ["catatan", "arsip"]
}
""";

Console.WriteLine(json);

int jumlah = 3;

string laporan = $$"""
Total catatan: {{jumlah}}
Status: {{(jumlah > 0 ? "aktif" : "kosong")}}
""";

Console.WriteLine(laporan);
text Keluaran
{
    "judul": "Aplikasi Catatan",
    "jumlahCatatan": 3,
    "kataKunci": ["catatan", "arsip"]
}
Total catatan: 3
Status: aktif

Keluaran menunjukkan isi JSON tercetak dengan indentasi empat spasi persis seperti yang ditulis, tanpa satu pun tanda kutip yang di-escape. Posisi penutup """ menentukan banyaknya indentasi yang dibuang, sehingga penutup yang disamakan dengan kolom isi menghasilkan teks yang terpotong rapi di sisi kiri. Pada contoh ini penutup berada di kolom paling kiri, sehingga seluruh indentasi isi tetap utuh.

Raw string terinterpolasi#

Awalan $$ pada bagian kedua program mengaktifkan interpolasi dengan kurung kurawal ganda {{ }}. Penggandaan tanda dolar menyelesaikan konflik yang muncul ketika teks memuat kurung kurawal tunggal, misalnya JSON atau skrip shell, karena satu kurung kurawal kini dianggap teks biasa. Ekspresi di dalam {{ }} diperlakukan seperti interpolasi biasa, termasuk perhitungan dan ekspresi bersyarat, sehingga baris Status: aktif berasal dari ekspresi bersyarat (ternary) (jumlah > 0 ? "aktif" : "kosong").

Apabila teksnya memuat kurung kurawal ganda sekaligus, awalan cukup ditambah lagi menjadi $$$ dengan kurung kurawal rangkap tiga untuk interpolasinya. Jumlah tanda dolar dan jumlah kurung kurawal interpolasi selalu berpasangan, sehingga aturannya mudah diingat pada teks yang semakin kompleks.

Split dan opsi pembersihan#

Metode Split memecah string menjadi array berdasarkan pemisah tertentu, dan hasil mentahnya sering memuat elemen kosong serta spasi sisa. Opsi StringSplitOptions.TrimEntries membuang spasi di kedua ujung setiap elemen, sedangkan RemoveEmptyEntries membuang elemen kosong yang muncul ketika dua pemisah berdampingan. Keduanya dapat digabungkan dengan operator |, dan anggota TrimEntries di antaranya ditambahkan pada .NET 5, sehingga pada basis kode yang lebih lama pembersihannya dilakukan manual.

csharp PengolahanTeks.cs
// Program: Split dengan opsi modern dan perbandingan string yang peka culture.
using System.Globalization;

string data = "ali; budi;; citra;  dewi ";

string[] namaBiasa = data.Split(';');
string[] namaBersih = data.Split(';',
    StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);

Console.WriteLine(string.Join("|", namaBiasa));
Console.WriteLine(string.Join("|", namaBersih));

CultureInfo turki = CultureInfo.CreateSpecificCulture("tr-TR");

Console.WriteLine("FILE".ToLowerInvariant());
Console.WriteLine("FILE".ToLower(turki));
Console.WriteLine(string.Equals("file", "FILE", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(string.Compare("file", "FILE", true, CultureInfo.InvariantCulture) == 0);
Console.WriteLine(string.Compare("file", "FILE", true, turki) == 0);
text Keluaran
ali| budi|| citra|  dewi 
ali|budi|citra|dewi
file
fıle
True
True
False

Baris pertama keluaran memperlihatkan hasil Split mentah yang masih menyimpan spasi di dalam elemen dan menyisakan satu elemen kosong dari pemisah ganda, sehingga tanda pisah | dari string.Join muncul dua kali berturut-turut. Baris kedua memperlihatkan hasil gabungan kedua opsi, yaitu empat nama bersih tanpa spasi sisa dan tanpa elemen kosong. Pemisahan seperti ini lazim pada berkas data yang dipisahkan titik koma, sehingga kedua opsi menghemat satu putusan pembersihan manual. Lima baris keluaran terakhir dihasilkan oleh bagian program yang belum dibahas, dan bagian berikutnya menjelaskannya.

Culture pada pembandingan string#

Dua baris berikutnya memperlihatkan pengaruh culture pada perubahan huruf. Metode ToLowerInvariant() menghasilkan file dengan aturan yang tidak berubah antarwilayah, sedangkan ToLower(turki) pada culture Turki tr-TR menghasilkan fıle yang memuat huruf i tanpa titik, karena dalam aturan Turki huruf I diturunkan menjadi ı dan bukan i. Karena itu pola a.ToLower() == b.ToLower() untuk membandingkan string menghasilkan jawaban yang berbeda pada komputer dengan culture berbeda, dan pola itu lebih baik dihindari.

Cara yang disarankan adalah memanggil pembandingan dengan penentu aturan secara eksplisit. Operator == dan metode string.Equals membandingkan karakter satu per satu secara ordinal, yaitu membandingkan kode karakternya langsung tanpa aturan bahasa, sehingga string.Equals("file", "FILE", StringComparison.OrdinalIgnoreCase) menghasilkan True di komputer mana pun. Untuk perbandingan yang peka aturan bahasa, metode seperti Compare menerima objek CultureInfo secara eksplisit. Baris True dari pembandingan invariant dan False dari pembandingan tr-TR pada keluaran di atas menunjukkan bahwa aturan yang sama dapat berbeda hasil antar culture, sehingga penentunya wajib disebut, bukan dititipkan pada pengaturan komputer.

Kesalahan umum#

  • Membandingkan string dengan ToLower() tanpa penentu culture. Hasilnya berubah mengikuti culture komputer, sebagaimana fıle pada culture Turki. Gunakan string.Equals dengan StringComparison yang disebut eksplisit.
  • Memecah teks tanpa opsi pembersihan. Hasil Split mentah memuat elemen kosong dan spasi sisa yang menyusahkan pemrosesan berikutnya. Gabungkan TrimEntries dan RemoveEmptyEntries bila masukannya berupa data yang ditulis manusia.
  • Lupa menggandakan tanda dolar pada raw string yang memuat kurung kurawal. Dengan awalan $, kurung kurawal tunggal pada JSON ditafsirkan sebagai interpolasi dan programnya gagal kompilasi. Gunakan $$ dengan {{ }} agar kurung kurawal tunggal tetap menjadi teks.

Ringkasan#

  • Raw string literal dari C# 11 diapit tiga tanda kutip atau lebih, menulis kutip dan garis miring terbalik apa adanya, dan posisi penutupnya menentukan indentasi yang dibuang.
  • Awalan $$ mengaktifkan interpolasi kurung kurawal ganda sehingga kurung kurawal tunggal pada JSON dan skrip tetap terbaca sebagai teks.
  • Opsi TrimEntries dan RemoveEmptyEntries pada Split sejak .NET 5 membersihkan spasi sisa dan elemen kosong dalam satu pemanggilan.
  • Pembandingan string perlu penentu aturan yang eksplisit, yaitu StringComparison untuk pembandingan ordinal atau CultureInfo untuk aturan bahasa, karena culture komputer dapat mengubah hasilnya.

Referensi#