Panduan Pasukan Lucee MY

Fungsi rentetan CFML: cari, ganti, potong dan format

Rujukan fungsi rentetan CFML untuk pembangun Lucee: find, replace, left, mid, trim, listToArray, numberFormat dan encodeForHTML dengan contoh kod yang diuji.

Fungsi rentetan CFML: cari, ganti, potong dan format
0
Kandungan

Fungsi rentetan CFML: cari, ganti, potong dan format

Rentetan ialah jenis data yang paling kerap anda sentuh dalam CFML, sama ada nama pengguna, teks artikel, URL, parameter pertanyaan atau nilai yang keluar daripada pangkalan data. Lucee membekalkan lebih seratus fungsi rentetan, tetapi sebahagian kecil daripadanya menampung hampir semua kerja harian: mencari, memotong, mengganti, memformat dan menyenaraikan. Panduan ini menyusun fungsi-fungsi itu mengikut tugas, dengan contoh kod yang dijalankan dalam Lucee sebenar, supaya anda tahu nilai yang setiap fungsi pulangkan.

Rentetan dalam CFML ialah java.lang.String

Satu fakta asas yang menentukan cara anda menulis kod: rentetan CFML sebenarnya objek java.lang.String daripada Java. Dua akibat praktikal mengikut fakta ini. Pertama, rentetan bersifat kekal, iaitu setiap fungsi memulangkan rentetan baharu dan tidak pernah mengubah rentetan asal. Kedua, operator perbandingan == berkelakuan seperti eq dalam CFML, iaitu perbandingan yang mengabaikan huruf besar atau kecil. Untuk perbandingan yang peka huruf, gunakan compare(), yang memulangkan 0 apabila sama, negatif apabila argumen pertama lebih kecil, dan positif apabila lebih besar.

<cfscript>
    a = "Lucee";
    b = "Lucee";
    c = "lucee";
    // compare() peka besar kecil, == abaikan besar kecil
    writeOutput("compare-sama=" & compare(a, b) & "<br>");
    writeOutput("compare-besar-kecil=" & compare(a, c) & "<br>");
    writeOutput("eq-besar-kecil=" & (a == c) & "<br>");
    // setiap fungsi memulangkan rentetan baharu, asal tidak berubah
    d = ucase(a);
    writeOutput("asal=" & a & "; selepas-ucase=" & d & "<br>");
</cfscript>

Contoh ini memulangkan compare-sama=0, compare-besar-kecil=-1 dan eq-besar-kecil=true, manakala asal=Lucee; selepas-ucase=LUCEE membuktikan rentetan asal tidak berubah. Inilah sebabnya kod yang mesti membezakan huruf menggunakan compare(a, b) eq 0, bukan a == b.

Fungsi carian

Keluarga fungsi find mencari subrentetan di dalam rentetan dan memulangkan kedudukan, iaitu indeks berasaskan satu, atau 0 jika tidak dijumpai. find() peka huruf, manakala findNoCase() mengabaikannya. findOneOf() mencari aksara pertama yang sepadan dengan mana-mana aksara dalam set yang diberi, berguna untuk mencari pembatas seperti ruang atau tanda baca. Untuk carian yang memerlukan pola, reFind() menerima ungkapan nalar (regex), dan reMatch() memulangkan senarai semua padanan. Sila rujuk panduan regex dengan reFind untuk pola yang lebih mendalam.

<cfscript>
    ayat = "Belajar Lucee CFML di Malaysia";
    writeOutput("find=" & find("Lucee", ayat) & "<br>");
    writeOutput("findNoCase=" & findNoCase("lucee", ayat) & "<br>");
    writeOutput("findOneOf=" & findOneOf("aeiou", ayat) & "<br>");
    writeOutput("find-tiada=" & find("xyz", ayat) & "<br>");
    teks = "No telefon: 012-3456789";
    m = refind("[0-9]{3}-[0-9]{7}", teks, 1, true);
    writeOutput("refind=" & m.pos[1] & " panjang " & m.len[1] & "<br>");
    padanan = rematch("[0-9]{3}-[0-9]{7}", teks);
    writeOutput("rematch=" & padanan[1] & "<br>");
    writeOutput("listFind=" & listFind("epal,pisang,mangga", "pisang") & "<br>");
    writeOutput("listFindNoCase=" & listFindNoCase("EPAL,PISANG", "epal") & "<br>");
</cfscript>

find("Lucee", ayat) memulangkan 9, kedudukan "Lucee" bermula, dan findOneOf("aeiou", ayat) memulangkan 2, kedudukan vokal pertama. reFind() tanpa argumen keempat memulangkan integer kedudukan sahaja; dengan argumen true ia memulangkan struktur pos dan len supaya anda boleh mengambil padanan penuh dengan mid(). listFind() dan listFindNoCase() menyemak kehadiran nilai dalam senarai dan memulangkan kedudukannya.

Fungsi potong dan ambil

Untuk mengambil sebahagian daripada rentetan, gunakan left() bagi aksara dari kiri, right() dari kanan, dan mid() bagi julat tengah. Ketiga-tiganya menggunakan indeks berasaskan satu. spanExcluding() memulangkan aksara dari permulaan sehingga bertemu aksara dalam set yang diberi, manakala spanIncluding() memulangkan aksara selagi ia berada dalam set itu. Untuk membuang ruang kosong di hujung, gunakan trim(), ltrim() dan rtrim().

<cfscript>
    s = "Lucee CFML Server";
    writeOutput("left=" & left(s, 5) & "<br>");
    writeOutput("right=" & right(s, 6) & "<br>");
    writeOutput("mid=" & mid(s, 7, 4) & "<br>");
    writeOutput("spanExcluding=" & spanExcluding(s, " C") & "<br>");
    writeOutput("spanIncluding=" & spanIncluding(s, "Luce") & "<br>");
    kotor = "   Lucee CFML   ";
    writeOutput("trim=[" & trim(kotor) & "] ltrim=[" & ltrim(kotor) & "] rtrim=[" & rtrim(kotor) & "]<br>");
</cfscript>

left(s, 5) memulangkan "Lucee", right(s, 6) memulangkan "Server", dan mid(s, 7, 4) memulangkan "CFML". spanExcluding(s, " C") memulangkan "Lucee" kerana ia berhenti pada ruang pertama, manakala spanIncluding(s, "Luce") juga memulangkan "Lucee" kerana aksara seterusnya ialah ruang yang tiada dalam set. Fungsi trim() penting sebelum menyimpan input borang, kerana ruang yang tidak kelihatan membuat dua nilai sama kelihatan berbeza.

Fungsi ganti

replace() menggantikan subrentetan dengan rentetan lain. Secara lalai ia menggantikan padanan pertama sahaja; lulus "all" sebagai argumen keempat untuk menggantikan semua. replaceNoCase() melakukan perkara yang sama tanpa mengambil kira huruf. Apabila anda memerlukan kuasa pola, reReplace() dan reReplaceNoCase() menggantikan padanan ungkapan nalar.

<cfscript>
    s = "Lucee itu pantas, lucee itu stabil";
    writeOutput("replace=" & replace(s, "lucee", "ColdFusion") & "<br>");
    writeOutput("replaceNoCase=" & replaceNoCase(s, "lucee", "ColdFusion", "all") & "<br>");
    teks = "kod-1234-cfml";
    writeOutput("reReplace=" & reReplace(teks, "[0-9]", "X", "all") & "<br>");
    writeOutput("reReplaceNoCase=" & reReplaceNoCase("LuCeE", "lucee", "Lucee") & "<br>");
</cfscript>

replace(s, "lucee", "ColdFusion") memulangkan "Lucee itu pantas, ColdFusion itu stabil" kerana ia hanya mencari huruf kecil "lucee" dan menggantikan padanan pertama. replaceNoCase(s, "lucee", "ColdFusion", "all") memulangkan "ColdFusion itu pantas, ColdFusion itu stabil" kerana ia menggantikan kedua-dua "Lucee" dan "lucee". reReplace() dengan [0-9] menukar setiap digit kepada X, menjadikannya alat yang berguna untuk menyelindung data sensitif atau menormalkan input.

Senarai sebagai rentetan

Dalam CFML, senarai hanyalah rentetan yang dipisahkan oleh pembatas, lazimnya koma. Kerana ia masih rentetan, semua fungsi rentetan boleh digunakan padanya, tetapi keluarga fungsi list memudahkan kerja dengan nilai yang dipisahkan. listLen() mengira bilangan item, listGetAt() mengambil item pada kedudukan tertentu, dan listAppend() menambah item di hujung. Untuk menukar antara senarai dan tatasusunan, gunakan listToArray() dan arrayToList(). Lihat juga panduan fungsi tatasusunan CFML untuk operasi tatasusunan yang lain.

<cfscript>
    senarai = "epal,pisang,mangga,durian";
    writeOutput("listLen=" & listLen(senarai) & "<br>");
    writeOutput("listGetAt=" & listGetAt(senarai, 2) & "<br>");
    writeOutput("listAppend=" & listAppend(senarai, "rambutan") & "<br>");
    arr = listToArray(senarai, ",");
    writeOutput("listToArray=" & arr[3] & "<br>");
    writeOutput("arrayToList=" & arrayToList(["a", "b", "c"], "-") & "<br>");
</cfscript>

Contoh ini memulangkan listLen=4, listGetAt=pisang, listAppend=epal,pisang,mangga,durian,rambutan, listToArray=mangga dan arrayToList=a-b-c. Semua fungsi senarai menerima argumen pembatas supaya anda boleh bekerja dengan rentetan yang dipisahkan titik bertindih, paip atau apa sahaja, bukan koma sahaja.

Format dan penukaran

Untuk paparan, numberFormat() membentuk nombor dengan corak topeng, dateFormat() dan timeFormat() membentuk tarikh dan masa, manakala lcase(), ucase() dan ucFirst() menukar huruf. Satu perkara penting untuk pembangun yang datang daripada Adobe ColdFusion: fungsi capitalize() dan lcFirst() tidak wujud dalam teras Lucee, dan memanggilnya memulangkan ralat "No matching function". Lucee menggantikan capitalize() dengan ucFirst(), yang menukar huruf pertama seluruh rentetan sahaja, bukan setiap perkataan.

<cfscript>
    writeOutput("numberFormat=" & numberFormat(1234567.891, "9,999.99") & "<br>");
    writeOutput("numberFormat-sifar=" & numberFormat(0.5, "0.00") & "<br>");
    writeOutput("dateFormat=" & dateFormat(createDate(2026, 10, 8), "dd mmm yyyy") & "<br>");
    writeOutput("timeFormat=" & timeFormat(createTime(14, 30, 0), "hh:mm tt") & "<br>");
    writeOutput("lcase=" & lcase("LUCEE") & "; ucase=" & ucase("lucee") & "<br>");
    writeOutput("ucFirst=" & ucFirst("selamat datang ke lucee") & "<br>");
</cfscript>

numberFormat(1234567.891, "9,999.99") memulangkan "1,234,567.89". dateFormat(createDate(2026, 10, 8), "dd mmm yyyy") memulangkan "08 Oct 2026", dan timeFormat(createTime(14, 30, 0), "hh:mm tt") memulangkan "02:30 PM". Nama bulan dan hari dalam dateFormat() bergantung pada locale pelayan, jadi jika anda mahukan "Ogos" dan bukan "Aug", tetapkan locale dahulu dengan setLocale(). ucFirst("selamat datang ke lucee") memulangkan "Selamat datang ke lucee", hanya huruf pertama yang berubah.

Enkod output dan keselamatan

Bahagian ini paling penting dari segi keselamatan. Apabila anda memaparkan data pengguna, anda mesti mengenkodnya supaya ia tidak menjadi kod yang boleh dilaksanakan. Lucee menawarkan dua fungsi yang kelihatan serupa tetapi berbeza dari segi perlindungan: htmlEditFormat() dan encodeForHTML(). Perbezaannya terletak pada petikan tunggal. htmlEditFormat() mengkod <, >, & dan petikan ganda, tetapi membiarkan petikan tunggal tidak dikod. encodeForHTML() mengkod petikan tunggal juga, menjadikannya pilihan yang selamat untuk output. Perincian penuh pertahanan XSS ada dalam panduan keselamatan web XSS dan CSRF.

<cfscript>
    mentah = "<script>alert('x')</script> & kopi";
    writeOutput("htmlEditFormat=" & htmlEditFormat(mentah) & "<br>");
    writeOutput("encodeForHTML=" & encodeForHTML(mentah) & "<br>");
    writeOutput("encodeForJavaScript=" & encodeForJavaScript("teks 'petik' dan ""dua""") & "<br>");
    writeOutput("urlEncodedFormat=" & urlEncodedFormat(mentah) & "<br>");
</cfscript>

htmlEditFormat() memulangkan &lt;script&gt;alert('x')&lt;/script&gt; &amp; kopi, perhatikan petikan tunggal di sekeliling x kekal mentah. encodeForHTML() memulangkan &lt;script&gt;alert(&#39;x&#39;)&lt;/script&gt; &amp; kopi, petikan tunggal itu bertukar kepada &#39;. Dalam atribut HTML yang menggunakan petikan tunggal sebagai pembatas, perbezaan ini bermakna serangan XSS boleh menembusi htmlEditFormat() tetapi tidak encodeForHTML(). Peraturan mudah: untuk apa-apa output HTML, guna encodeForHTML(). encodeForJavaScript() menyediakan rentetan untuk dimasukkan ke dalam kod JavaScript, dan urlEncodedFormat() mengekod rentetan untuk digunakan dalam URL.

Enkod aksara dan masalah mojibake

Mojibake ialah nama bagi teks yang menjadi aksara pelik seperti "kafé" atau "Selamat Datang “". Ia berlaku apabila bait UTF-8 dibaca menggunakan set aksara yang salah, lazimnya ISO-8859-1. Satu aksara seperti "é" ialah dua bait dalam UTF-8 tetapi satu bait dalam ISO-8859-1, jadi membaca bait UTF-8 sebagai Latin-1 menghasilkan aksara sampah. Contoh berikut menunjukkan perbezaan kiraan aksara dan bait menggunakan kaedah Java yang disokong.

<cfscript>
    cfheader(name = "Content-Type", value = "text/html; charset=utf-8");
    teks = "kaf" & chr(233);
    bait = createObject("java", "java.lang.String").init(teks).getBytes("UTF-8");
    writeOutput("teks=" & teks & "; aksara=" & len(teks) & "; bait-utf8=" & arrayLen(bait) & "<br>");
    baitIso = createObject("java", "java.lang.String").init(teks).getBytes("ISO-8859-1");
    writeOutput("bait-iso=" & arrayLen(baitIso) & "<br>");
</cfscript>

Rentetan "kafé" mempunyai 4 aksara tetapi 5 bait dalam UTF-8, kerana "é" ialah dua bait. Dalam ISO-8859-1 ia hanya 4 bait. Untuk mengelakkan mojibake, tetapkan UTF-8 pada setiap lapisan: simpan fail sebagai UTF-8, isytiharkan charset dalam cfheader, tetapkan pengekodan pada sambungan pangkalan data, dan pastikan borang HTML menggunakan accept-charset. Mojibake hanya muncul apabila satu lapisan membaca bait dengan set aksara yang berbeza daripada lapisan yang menulisnya.

Jadual rujukan pantas

KategoriFungsiTujuan
Perbandingancompare(), compareNoCase()Banding dua rentetan, peka atau abai huruf
Carianfind(), findNoCase(), findOneOf()Cari subrentetan atau aksara dalam set
Carian regexreFind(), reMatch()Cari dengan ungkapan nalar
SenarailistFind(), listFindNoCase()Cari nilai dalam senarai dipisah koma
Potongleft(), right(), mid()Ambil aksara dari kiri, kanan atau tengah
Julat aksaraspanExcluding(), spanIncluding()Ambil sehingga atau selagi aksara dalam set
Buang ruangtrim(), ltrim(), rtrim()Buang ruang kosong di hujung
Gantireplace(), replaceNoCase()Ganti subrentetan, padanan pertama atau semua
Ganti regexreReplace(), reReplaceNoCase()Ganti padanan ungkapan nalar
SenarailistLen(), listGetAt(), listAppend()Kira, ambil dan tambah item senarai
Tukar jenislistToArray(), arrayToList()Tukar antara senarai dan tatasusunan
FormatnumberFormat(), dateFormat(), timeFormat()Bentuk nombor, tarikh dan masa
Huruflcase(), ucase(), ucFirst()Tukar besar kecil huruf
Enkod outputencodeForHTML(), encodeForJavaScript(), urlEncodedFormat()Enkod untuk output yang selamat

Soalan Lazim (FAQ)

Apakah perbezaan antara compare() dan operator ==?

compare() memulangkan 0 apabila sama, negatif atau positif mengikut susunan, dan ia peka huruf. Operator == bersamaan eq dalam CFML dan mengabaikan huruf besar atau kecil, jadi "lucee" sama dengan "LUCEE" di bawah == tetapi berbeza di bawah compare().

Bilakah saya patut guna reFind berbanding find?

Guna find() untuk subrentetan yang tepat dan tetap. Guna reFind() apabila anda perlu memadankan pola, contohnya semua digit atau format nombor telefon. reFind() menerima ungkapan nalar manakala find() hanya menerima teks literal.

Kenapa capitalize() tidak berfungsi dalam Lucee?

capitalize() ialah fungsi Adobe ColdFusion yang tidak dibawa ke dalam teras Lucee. Lucee menyediakan ucFirst() untuk menukar huruf pertama, dan ucase() serta lcase() untuk keseluruhan rentetan. Panggilan capitalize() memulangkan "No matching function".

Apakah beza encodeForHTML() dan htmlEditFormat()?

htmlEditFormat() mengkod <, >, & dan petikan ganda tetapi meninggalkan petikan tunggal tidak dikod. encodeForHTML() mengkod petikan tunggal juga. Untuk output yang selamat daripada XSS, sentiasa guna encodeForHTML().

Bagaimana saya mengelakkan mojibake dalam teks Bahasa Melayu?

Tetapkan UTF-8 secara konsisten pada setiap lapisan: simpan fail sumber sebagai UTF-8, hantar header Content-Type dengan charset=utf-8, tetapkan pengekodan sambungan pangkalan data kepada UTF-8, dan isytiharkan accept-charset pada borang. Mojibake berlaku hanya apabila satu lapisan membaca bait dengan set aksara yang berbeza daripada lapisan yang menulisnya.

Sumber

Senarai semak

  1. Guna compare() untuk perbandingan yang peka huruf, bukan ==.
  2. Ingat bahawa find() dan fungsi kedudukan lain memulangkan indeks berasaskan satu, dan 0 jika tiada padanan.
  3. Lulus "all" kepada replace() dan replaceNoCase() apabila anda mahu menggantikan setiap padanan.
  4. Guna listToArray() dan arrayToList() untuk berpindah antara senarai dan tatasusunan.
  5. Jangan panggil capitalize() atau lcFirst() dalam Lucee; guna ucFirst().
  6. Enkod semua output data pengguna dengan encodeForHTML(), bukan htmlEditFormat().
  7. Tetapkan UTF-8 pada fail, header, pangkalan data dan borang untuk mengelakkan mojibake.
Bab 8 daripada 13

Asas CFML untuk Pemula

Log masuk untuk menyimpan kemajuan bacaan anda.

0 komen

0 komen

Log masuk untuk menjawab atau memberi komen.

Log masuk