HTML / XML dibagi menjadi markup dan konten. Regex hanya berguna melakukan penguraian tag leksikal. Saya kira Anda dapat menyimpulkan konten. Ini akan menjadi pilihan yang baik untuk parser SAX. Tag dan konten dapat dikirimkan ke fungsi yang ditentukan pengguna di mana elemen / penutupan elemen dapat dilacak.
Sejauh hanya mengurai tag, itu bisa dilakukan dengan regex dan digunakan untuk menghapus tag dari dokumen.
Selama bertahun-tahun pengujian, saya telah menemukan rahasia cara tag parse browser, baik dan buruk terbentuk.
Elemen normal diuraikan dengan bentuk ini:
Inti dari tag ini menggunakan regex ini
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
Anda akan melihat ini [^>]?
sebagai salah satu alternatif. Ini akan cocok dengan kutipan yang tidak seimbang dari tag yang dibentuk dengan buruk.
Itu juga, satu-satunya akar dari semua kejahatan untuk ekspresi reguler. Cara yang digunakan akan memicu benturan untuk memenuhi wadahnya yang serakah dan harus dicocokkan.
Jika digunakan secara pasif, tidak pernah ada masalah Tapi, jika Anda memaksakan sesuatu untuk mencocokkan dengan menyelingi dengan pasangan atribut / nilai yang diinginkan, dan tidak memberikan perlindungan yang memadai dari pengulangan, itu adalah mimpi buruk yang tidak terkendali.
Ini adalah bentuk umum untuk tag lama biasa. Perhatikan yang [\w:]
mewakili nama tag? Pada kenyataannya, karakter hukum yang mewakili nama tag adalah daftar karakter Unicode yang luar biasa.
<
(?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
>
Selanjutnya, kami juga melihat bahwa Anda tidak dapat mencari tag tertentu tanpa menguraikan SEMUA tag. Maksud saya Anda bisa, tetapi harus menggunakan kombinasi kata kerja seperti (* SKIP) (* GAGAL) tetapi semua tag harus diuraikan.
Alasannya adalah bahwa sintaksis tag mungkin disembunyikan di dalam tag lain, dll.
Jadi, untuk mem-parsing semua tag secara pasif, diperlukan regex seperti di bawah ini. Yang satu ini juga cocok dengan konten yang tidak terlihat .
Saat HTML baru atau xml atau lainnya mengembangkan konstruksi baru, tambahkan saja sebagai salah satu alternatif.
Catatan halaman web - Saya belum pernah melihat halaman web (atau xhtml / xml) yang
bermasalah dengannya. Jika Anda menemukannya, beri tahu saya.
Catatan kinerja - Cepat. Ini adalah tag parser tercepat yang pernah saya lihat
(mungkin ada yang lebih cepat, siapa tahu).
Saya punya beberapa versi spesifik. Ini juga sangat baik sebagai scraper
(jika Anda tipe tangan).
Regex mentah lengkap
<(?:(?:(?:(script|style|object|embed|applet|noframes|noscript|noembed)(?:\s+(?>"[\S\s]*?"|'[\S\s]*?'|(?:(?!/>)[^>])?)+)?\s*>)[\S\s]*?</\1\s*(?=>))|(?:/?[\w:]+\s*/?)|(?:[\w:]+\s+(?:"[\S\s]*?"|'[\S\s]*?'|[^>]?)+\s*/?)|\?[\S\s]*?\?|(?:!(?:(?:DOCTYPE[\S\s]*?)|(?:\[CDATA\[[\S\s]*?\]\])|(?:--[\S\s]*?--)|(?:ATTLIST[\S\s]*?)|(?:ENTITY[\S\s]*?)|(?:ELEMENT[\S\s]*?))))>
Tampilan diformat
<
(?:
(?:
(?:
# Invisible content; end tag req'd
( # (1 start)
script
| style
| object
| embed
| applet
| noframes
| noscript
| noembed
) # (1 end)
(?:
\s+
(?>
" [\S\s]*? "
| ' [\S\s]*? '
| (?:
(?! /> )
[^>]
)?
)+
)?
\s* >
)
[\S\s]*? </ \1 \s*
(?= > )
)
| (?: /? [\w:]+ \s* /? )
| (?:
[\w:]+
\s+
(?:
" [\S\s]*? "
| ' [\S\s]*? '
| [^>]?
)+
\s* /?
)
| \? [\S\s]*? \?
| (?:
!
(?:
(?: DOCTYPE [\S\s]*? )
| (?: \[CDATA\[ [\S\s]*? \]\] )
| (?: -- [\S\s]*? -- )
| (?: ATTLIST [\S\s]*? )
| (?: ENTITY [\S\s]*? )
| (?: ELEMENT [\S\s]*? )
)
)
)
>