مشكلة Regex - استرجاع محتوى العلامة مع فئة معينة - preg_match (_all)
-
16-09-2019 - |
سؤال
أحتاج إلى استرداد محتوى <p>
علامة مع فئة معين. الفئة يمكن أن يكون simplecomment
أو comment
...
لذلك كتبت الكود التالي
preg_match("|(<p class=\"(simple)?comment(.*)?\">)(.*)<\/p>|ism", $fcon, $desc);
لسوء الحظ، فإنه لا يعد شيئا. ومع ذلك، إذا قمت بإزالة جزء العلامات المنتهي (<\/p>
) يعمل بطريقة أو بأخرى، واسحب السلسلة التي هي طويلة جدا (بدءا من العلامة إلى نهاية المستند) ...
ما هو الخطأ في تعبيري العادي؟
المحلول
حاول استخدام محلل دوم مثل http://simplehtmldom.sourceforge.net/
إذا قرأت رمز المثال على الصفحة الرئيسية Simplehtmldom في الصفحة الرئيسية بشكل صحيح، فيمكنك القيام بشيء مثل هذا:
$html->find('div.simplecomment', 0)->innertext = '';
نصائح أخرى
الإصلاح السريع هنا هو التالي:
'|(<p class="(simple)?comment[^"]*">)((?:[^<]+|(?!</p>).)*)</p>|is'
التغييرات:
- البناء
(.*)
سوف تطابق فقط عمياء كل شيء، مما يمنع تعبيرك المنتظم عن العمل، لذلك استبدلت هذه الحالات تماما مع تطابق أكثر صرامة:- ...
comment(.*)?
... - هذا سيطابق كل شيء أو لا شيء، أساسا. أنا استبدال هذا مع[^"]*
منذ ذلك الحين سوف تتطابق مع الصفر أو أكثر من غير"
الأحرف (أساسا، سوف تتطابق مع الإغلاق"
شخصيةclass
ينسب. - ...
>)(.*)<\/p>
... - مرة أخرى، هذا سوف يتطابق كثيرا. لقد استبدلتها بنمط فعال من شأنه أن يتطابق مع كل غير<
الشخصيات، وبمجرد يضرب<
سوف تحقق مما إذا كان يتبعه</p>
. وبعد إذا كان الأمر كذلك، فسوف يتوقف مطابقة (لأننا في نهاية<p>
علامة)، وإلا وسوف تستمر.
- ...
- أزلت
m
العلم لأنه ليس له استخدام في هذا التعبير العادي.
لكن لن تكون موثوقة (تخيل <p class="comment">...<p>...</p></p>
; ؛ سوف تتطابق <p class="comment">...<p>...</p>
).
لجعلها موثوقة، ستحتاج إلى استخدام التعبيرات العادية المتكررة أو (حتى أفضل) محلل HTML (أو XML إذا كان XHTML أنت تتعامل معها.) هناك حتى مكتبات يمكن أن تتعامل مع HTML "بشكل صحيح" ( مثل المتصفحات تفعل.)