Я понимаю, так как Regex по существу не имеет состояния, довольно сложно добиться сложных совпадений, не прибегая к дополнению логики приложения, однако мне любопытно узнать, возможно ли следующее.
Совпадение всех пробелов, достаточно просто: \s+
Но пропустите пробел между определителями, в моем случае <pre>
и </pre>
слово nostrip
.
Есть ли какие-нибудь хитрости для достижения этой цели?Я думал о двух разных матчах, один для всех пробелов и один для <pre>
блоков ноздрейных секций , и как-то отрицал последние из первых.
"This is some text NOSTRIP this is more text NOSTRIP some more text."
// becomes
"ThisissometextNOSTRIP this is more text NOSTRIPsomemoretext."
Вложение данных тегов разделов ноздри не имеет значения, и я не пытаюсь проанализировать дерево HTML или что-либо еще, просто приведя в порядок текстовый файл , но сохранив пробелы в <pre>
блоках разделах ноздри по понятным причинам.
( лучше? )
Это в конечном счете то, с чем я столкнулся.Я уверен, что он может быть оптимизирован в нескольких местах, но пока он работает хорошо.
public function stripWhitespace($html, Array $skipTags = array('pre')){
foreach($skipTags as &$tag){
$tag = "<{$tag}.*?/{$tag}>";
}
$skipped = array();
$buffer = preg_replace_callback('#(?<tag>' . implode('|', $skipTags) . ')#si',
function($match) use(&$skipped){
$skipped[] = $match['tag'];
return "\x1D" . (count($skipped) - 1) . "\x1D";
}, $html
);
$buffer = preg_replace('#\s+#si', ' ', $buffer);
$buffer = preg_replace('#(?:(?<=>)\s|\s(?=<))#si', '', $buffer);
for($i = count($skipped) - 1; $i >= 0; $i--){
$buffer = str_replace("\x1D{$i}\x1D", $skipped[$i], $buffer);
}
return $buffer;
}