Regex для автоматизации некоторых меток HTML

У меня есть 800 записей, которые очень похожи, но им нужен некоторый материал, сделанный им. Формат похож на это:

<td class="description">
Describing text.
Might very well be 2 paragraphs
</td>

Я должен сделать некоторый материал к тексту в ячейке. Я попытался использовать preg_replace (' / (. +) </td> / '). Это заканчивается с двумя проблемами.

  1. Мне не удается выбрать то, что в круглой скобке, но она также выберет теги ячейки.
  2. Это выберет все до последнего </td> в документе. Я просто хочу, чтобы это перешло к первому вхождению </td>

Заранее спасибо

1
задан Anders 14 July 2010 в 13:47
поделиться

6 ответов

Прежде всего,. + Захватит все ... он не будет начинаться только с . Вам нужно будет добавить регулярное выражение для извлечения начала таблицы col:

<td[^>]*?>

(примечание, [^>] * означает совпадение не- > символов, пока мы не найдем его. )

Кроме того, . + и . * являются жадными , что означает, что он захватит как можно больше. Чтобы изменить это поведение, добавьте после него ? , например: . +? . Это позволяет ему удовлетворять ровно столько, сколько нужно.

Итак, у вас будет

<td[^>]*)>(.*?)<\/td>

Это был урок по регулярным выражениям, но я действительно думаю, что вам не следует использовать для этого регулярные выражения. Regex может довольно легко сломаться, если у вас появятся вложенные таблицы или что-то более сложное, чем простой html.

1
ответ дан 2 September 2019 в 23:03
поделиться

D̨͙̯̹̼ỏ͇̥̱͚̲͖̣͢ǹ̶̥͉̳͈͈̏̉ͧ'ͧͬ͏̪̩͓̳̬̱ͅt͇̝̖ͦ̏̏̍̉͠ ͙̺̹͚͎̐̒ͥ͑̀ṷ͍̖͕̐ͫ̚s̤͖͇̲̪͊͋̉ͨͪ̚e͚̲͎͓̟͊̍ ̲̬̩͇̗̭̌̊̑̊͝r̷̦͔̞̜̬ͦe̔̓͒͊̌g̹̘̬̭ͨ̐̽̐̂u̼̹̔ͣ͑͐̓͋l͈̤̘͉̰̏͌̚a̵̤̞̥̋rͭ ̦̝͓̟̣̯̄́̎̀̔ͥe̢̟̥̹̊̅̌̅̋x̠̠̲͚̝͋ͪp̧̽̉ṟ͉̏͌̊̐ͅe͖͎̞͇̽͛̀s͓͈̒s̴͚̮̹ͧ̽i̐ͪ̈́̏̑o͇͓̎n͎̐̃ͨ͢s̜͉̼̹͇̐ͥ̏̈́̽̔͐ ̛̑ͧf̩̋ͨ͑ö̮̗̩́̏̀ͩ̆r̮͓͊̌ ̸̪͈̫̬̭̻̮͊ͧ͂ͬ̌H͎̤̟͙̞ͪ͐̃̿ͮͭͅT͚̉͑͛̉M̴̦͖͇͔͚̙ͭͭ̽L͗ͦ̋̓͑ ͍͈͙̞͍̻̉̆͆̃͘p̓̉̃͆͛ͦ́͟r͕͙ͭͭͦ͡ő̹͍̳̳ͯ̐c̵̙͇͋̅è͖̘̲̰͉͉̺͛́ͪͩ̋͜s̾͑ͬͬ͐̋̀s̜̼̰̞̺͗ͫ̒ͫͧͥͅḭ̪ͫ͋ͫ̚n̿͐҉̺̩̟̻̳g͑̀̑̆̈̾! ̠̓ͭ̈͜

Если вы все еще хотите попробовать... используйте группы без захвата (?:) для исключения тегов и ленивый квантификатор *? для соответствия только до первого закрывающего тега.

(?:<td[^>]*>).*?(?:</td>)

Это требует режима dot-all и может не сработать, если, например, атрибут description содержит закрывающую угловую скобку.

1
ответ дан 2 September 2019 в 23:03
поделиться

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

// $entries contains all of the table cell entries.
$newentries = "";
$cells = split("</td>",$entries);
while (list(,$data) = each($cells)) {
    $newentries .= "<td class=\"description\">";
    $text = substr($data,strpos($data, ">") + 1);
    // perform modifications on $text
    // i.e. $text = "<B>" . $text . "</B>";
    $newentries .= $text;
    $newentries .= "</td>";
}

// $newentries now contains the modified cell entries.

Вероятно, это не на 100% то, что вы ищете, но, возможно, это поможет.

0
ответ дан 2 September 2019 в 23:03
поделиться

Как уже сказали все остальные: RegExp - это плохо, по крайней мере здесь!

Итак, базовый Regex это

#<td[^>]*>(.*?)</td>#s

(Обратите внимание, я использовал s-модификатор, иначе RegExp не работал бы.)

Итак, этот RegExp неправильный, хотя он может быть подходящим для ваших целей. Чтобы быть более строгим, вы должны знать, что > разрешено в атрибутах. Поэтому этот регекс может все сломать.

#<td(\s+\w+="[^"]+")\s*>(.*?)</td>#s

Я думаю, что теперь это будет вполне безопасно, если вы имеете дело с XML. Но, конечно, он может сломаться в редких случаях, о которых я сейчас не могу вспомнить.

0
ответ дан 2 September 2019 в 23:03
поделиться
$d = new DOMDocument();
$d->loadHTML($htmlstring);
$x = new DOMXPath($d);
$tds = $x->query("//td[@class='description']//text()");
for($i = 1; $i <= $tds->length; $i++){
    $tds->item($i)->replaceData(0,mb_strlen($tds->item($i)->wholeText),strtoupper($tds->item($i)->wholeText));   
}
var_dump($d->saveHTML());
0
ответ дан 2 September 2019 в 23:03
поделиться

Вы можете использовать:

preg_replace(
  '/<td (.*?)>(.*?)<\/td>/sm',
  '<td class="description"><strong>$2</strong></td>',
  $data
)

Если то, что вы пытаетесь сделать с текстом внутри, усложняйте, используйте функцию обратного вызова.

0
ответ дан 2 September 2019 в 23:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: