ฉันยอมรับว่าเครื่องมือที่เหมาะสมในการแยกวิเคราะห์ XML และโดยเฉพาะอย่างยิ่ง HTMLเป็นเครื่องมือแยกวิเคราะห์ไม่ใช่เครื่องมือแสดงผลปกติ อย่างไรก็ตามเช่นเดียวกับที่คนอื่น ๆ ชี้บางครั้งการใช้ regex นั้นเร็วกว่าง่ายขึ้นและทำงานให้เสร็จถ้าคุณรู้ว่ารูปแบบข้อมูล
ไมโครซอฟท์จริงมีส่วนของการปฏิบัติที่ดีที่สุดสำหรับการแสดงผลปกติใน .NET Frameworkและโดยเฉพาะพูดคุยเกี่ยวกับการพิจารณา [วัน] การป้อนข้อมูลแหล่งที่มาของ
นิพจน์ทั่วไปมีข้อ จำกัด แต่คุณได้พิจารณาสิ่งต่อไปนี้หรือไม่
กรอบ NET เป็นที่ไม่ซ้ำกันเมื่อมันมาถึงการแสดงผลปกติในการที่จะสนับสนุนBalancing กลุ่มนิยาม
ด้วยเหตุผลนี้ฉันเชื่อว่าคุณสามารถแยกวิเคราะห์ XML โดยใช้นิพจน์ทั่วไป อย่างไรก็ตามโปรดทราบว่ามันจะต้องเป็น XML ที่ถูกต้อง ( เบราว์เซอร์นั้นมีการอภัย HTML มากและอนุญาตให้ใช้ไวยากรณ์ XML ที่ไม่ดีภายใน HTML ) สิ่งนี้เป็นไปได้เนื่องจาก "Balancing Group Definition" จะทำให้เอ็นจินนิพจน์ทั่วไปทำหน้าที่เป็น PDA
อ้างอิงจากบทความ 1 ที่อ้างถึงข้างต้น:
. NET Expression Engine
ดังที่อธิบายไว้ข้างต้นโครงสร้างที่สมดุลอย่างเหมาะสมไม่สามารถอธิบายได้ด้วยนิพจน์ทั่วไป อย่างไรก็ตามเอ็นจิ้นนิพจน์ทั่วไป. NET มีโครงสร้างจำนวนน้อยที่อนุญาตให้สร้างโครงสร้างที่สมดุลได้รับการยอมรับ
(?<group>)
- พุชผลลัพธ์ที่ถูกดักจับสแต็กด้วยกลุ่มชื่อ
(?<-group>)
- ป๊อปอัปดักจับส่วนใหญ่ที่มีกลุ่มชื่อปิดกองซ้อน
(?(group)yes|no)
- จับคู่ส่วนที่ใช่ถ้ามีกลุ่มที่มีกลุ่มชื่ออยู่ไม่เช่นนั้นจะไม่มีส่วนใด ๆ
โครงสร้างเหล่านี้อนุญาตให้นิพจน์ปกติ. NET เลียนแบบ PDA ที่ถูก จำกัด โดยอนุญาตให้มีการดำเนินการสแต็กรุ่นง่าย ๆ : push, pop และ empty การดำเนินการอย่างง่ายนั้นมีค่าเทียบเท่ากับการเพิ่มการลดลงและการเปรียบเทียบกับศูนย์ตามลำดับ สิ่งนี้อนุญาตให้เอ็นจินนิพจน์ปกติ. NET จดจำชุดย่อยของภาษาที่ไม่มีบริบทโดยเฉพาะอย่างยิ่งภาษาที่ต้องการตัวนับอย่างง่าย สิ่งนี้จะช่วยให้นิพจน์ทั่วไป. NET ที่ไม่ใช่แบบดั้งเดิมรู้จักโครงสร้างที่สมดุลอย่างเหมาะสม
พิจารณาการแสดงออกปกติต่อไปนี้:
(?=<ul\s+id="matchMe"\s+type="square"\s*>)
(?>
<!-- .*? --> |
<[^>]*/> |
(?<opentag><(?!/)[^>]*[^/]>) |
(?<-opentag></[^>]*[^/]>) |
[^<>]*
)*
(?(opentag)(?!))
ใช้ธง:
- แถวเดียว
- IgnorePatternWhitespace (ไม่จำเป็นถ้าคุณยุบ regex และลบ whitespace ทั้งหมด)
- IgnoreCase (ไม่จำเป็น)
อธิบายนิพจน์ปกติ (แบบอินไลน์)
(?=<ul\s+id="matchMe"\s+type="square"\s*>) # match start with <ul id="matchMe"...
(?> # atomic group / don't backtrack (faster)
<!-- .*? --> | # match xml / html comment
<[^>]*/> | # self closing tag
(?<opentag><(?!/)[^>]*[^/]>) | # push opening xml tag
(?<-opentag></[^>]*[^/]>) | # pop closing xml tag
[^<>]* # something between tags
)* # match as many xml tags as possible
(?(opentag)(?!)) # ensure no 'opentag' groups are on stack
คุณสามารถลองนี้ที่ดีกว่า .NET นิพจน์ปกติ Tester
ฉันใช้ตัวอย่างแหล่งที่มาของ:
<html>
<body>
<div>
<br />
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
</div>
</body>
</html>
พบการแข่งขันนี้:
<ul id="matchMe" type="square">
<li>stuff...</li>
<li>more stuff</li>
<li>
<div>
<span>still more</span>
<ul>
<li>Another >ul<, oh my!</li>
<li>...</li>
</ul>
</div>
</li>
</ul>
แม้ว่ามันจะออกมาแบบนี้จริง ๆ :
<ul id="matchMe" type="square"> <li>stuff...</li> <li>more stuff</li> <li> <div> <span>still more</span> <ul> <li>Another >ul<, oh my!</li> <li>...</li> </ul> </div> </li> </ul>
สุดท้ายนี้ผมมีความสุขจริงๆบทความเจฟฟ์แอด: แยก Html ธู Way ตลกพอมันอ้างอิงคำตอบสำหรับคำถามนี้ที่ปัจจุบันมีมากกว่า 4k โหวต