Замена текстового узла ввода HTML в PHP - PullRequest
0 голосов
/ 24 декабря 2010

Я хочу заменить все текстовые узлы в HTML-текст.Я объясню на примере: $ html = "

<div>
    <p>
        text2 text2 word text2
        <span>abcd</span>
        text2 text2 word text2
    <p>
    this is a long, very long statement with punctuations.
</div>

Я хочу заменить" text2 text2 word text2 "на" <span>text2 text2 word text2</span> "и" this is a long, very long statement with punctuations. "на" <span>this is a long, very long statement with punctuations.</span> "

Каким должно быть регулярное выражение для одного и того же?

1 Ответ

0 голосов
/ 24 декабря 2010

Обычно это кто-то, кто советует использовать анализатор HTML. И действительно, это было бы более надежным для этой задачи. Обычно QueryPath или phpQuery также проще для глаз:

$p = phpQuery::newDocumentHTML($h);
$p->find("p")->not("span")->wrap("span");

Но в этом случае я потерпел неудачу. Это немного черное искусство, если вы не знаете всех волшебных селекторов jQuery (а в phpQuery их все равно нет). Ваш случай сложен, так как вы хотите работать с отдельными текстовыми узлами. Следовательно, вам действительно придется использовать DOMDocument для индивидуального сканирования документа. Это, конечно, выполнимо, но слишком много API для меня. :}

Так что я пропустил прямо к подходу регулярных выражений, который с большой осторожностью был бы реально осуществим:

 print preg_replace(
     '#(?<!<span)>(\s*)(\w[\w,.\h]+)(\s*)<#',
     '>$1<span>$2</span>$3<',
     $html);

Фактический трюк - это утверждение за кадром (?<!<span), поэтому он не будет соответствовать тексту, уже заключенному в промежутки. Это выглядит более запутанным, потому что я сделал так, чтобы он совпадал с пробелами \s и горизонтальными \h по отдельности и включил его в более приятную структуру вывода. Вам нужно будет изменить [\w,.\h], чтобы включить все возможные дополнительные символы в последнюю строку. Вот где подход регулярных выражений показывает его слабость - вы не можете позволить ему соответствовать < или >. И если ваши текстовые строки на самом деле являются абзацами, вам придется отменить разделение \ s и \ h.

Итак, снова работает для вашего простого случая. Но DOM-подходы обычно более надежны .

...