javascript - RegExp tidak berfungsi pada fail HTML yang dibaca


Pertama sekali, saya tahu bagaimana kebanyakan soalan RegExp pergi; dan ini bukan salah satu daripada soalan, "sila tulis kod saya" itu.

Kekeliruan saya terletak pada hakikat bahawa RegExp saya berfungsi di regexr, dan dalam alat pembangunan Chrome ketika memeriksa document.body.textContent, tetapi tidak pada fail HTML selepas saya membacanya dalam io.js.

io.js ialah versi 1.5.1, dijalankan pada Windows 8

Mengapa ia berfungsi di kedua-dua tempat yang disenaraikan, tetapi tidak di io.js? Adakah saya tidak mengambil kira sesuatu yang dilakukan io.js untuk membaca fail?

RegExp saya sepatutnya memadankan "@{each ___->___} teks dan pemisah baris @{/each}" seperti yang dilakukan dalam pautan di bawah, tetapi sebaliknya, ia mengembalikan null

Ini adalah apa yang saya cuba gunakan: http://regexr.com/3aldk

RegExp :

/@\{each ([a-zA-Z0-9->.]*)\}([\s\S]*)@\{\/each}/g

JS (Contoh):

fs.readFile('view.html', {encoding:'utf8'}, function(error, html) {
    console.log(html.match(myRegExp)); // null
});

HTML :

<!doctype html>
<html>
    <head>
        <title>@{title}</title>
    </head>
    <body>
        <h1>@{foo.bar}</h1>
        <p>
            Lorem ipsum dolor sit amet, @{foo.baz.hoo}
        </p>
        @{each people->person}
            <div>
                <b>@{person.name}:</b> @{person.age}
            </div>
        @{/each}
    </body>
</html>

Adakah saya terlepas sesuatu yang jelas, seperti satu watak, yang ada di bahagian belakang, tetapi tidak pernah muncul sekali pun?

Jawapan #1

Isu di sini terletak pada garis halus antara spesifikasi dan pelaksanaan.

Spesifikasi ECMAscript 5.1 menyatakan bahawa:

Watak - boleh dianggap secara literal atau ia boleh menunjukkan julat. Ia dianggap secara literal jika ia adalah watak pertama atau terakhir dalam ClassRanges, had permulaan atau akhir spesifikasi julat, atau segera mengikuti spesifikasi julat.

Regular-Expressions.info mencatat bahawa:

Tanda sempang di kedudukan lain dalam kelas aksara di mana ia tidak boleh membentuk julat mungkin ditafsirkan sebagai literal atau sebagai ralat. Rasa regex agak tidak konsisten mengenai hal ini.

Kesimpulan :

Cara selamat untuk memasukkan tanda tolak - dalam kelas watak adalah dengan salah satu daripada:

  • mengelakkannya (contoh: [a-zA-Z0-9\->.])
  • meletakkannya sebagai aksara pertama dalam kelas (contohnya [-.>a-zA-Z0-9])

    • exception: dalam kelas yang dinafikan ia pergi ke kedudukan ke-2, tepat selepas ^ (contoh: [^-.>a-zA-Z0-9])
  • meletakkannya terakhir dalam kelas (contoh: [a-zA-Z0-9.>-])

Garis panduan pengekodan am mencadangkan meletakkan julat anda terlebih dahulu dan menamatkan kelas aksara dengan tanda sengkang, ini mengelakkan kekeliruan dan membantu keterbacaan.

Kesimpulannya, RegEx anda sepatutnya menjadi:

/@\{each ([a-zA-Z0-9>.-]*)\}([\s\S]*)@\{\/each}/g

Sebagai petua tambahan:

anda juga boleh menulis semula [\s\S] (mana-mana aksara ruang kosong atau mana-mana aksara bukan ruang kosong) ke dalam [^] (bukan tiada)

yang akan menjadikan anda dengan RegEx berikut:

/@\{each ([a-zA-Z0-9>.-]*)\}([^]*)@\{\/each}/g

JavaScript ... menganggap [^] sebagai kelas aksara kosong yang dinafikan yang sepadan dengan mana-mana aksara tunggal. - sumber