Вы говорите, что не собираетесь анализировать xml, а затем продолжаете показывать пример xml. Это немного сбивает с толку.
Теперь причина, по которой вы не можете использовать регулярные выражения для разбора xml, заключается в том, что они не являются контекстными. Поэтому существует целый класс проблем, для которых нельзя использовать регулярные выражения. Это включает в себя вложенные теги (будь то XML или нет), так что имейте это в виду.
Это, кстати, вы должны использовать preg
- не ereg
. ereg
- это наименее используемый, более медленный и теперь устаревший тип регулярных выражений. Просто забудь об этом.
В pcre (регулярные выражения, совместимые с Perl), который использует язык preg, .
(точка) - это подстановочный знак, который соответствует любому отдельному символу (кроме новой строки). Вы можете поставить квантификатор после матча. Квантификатор может быть явным диапазоном чисел, таким как {1,3}
(означающий, по крайней мере, один, но не более 3), или вы можете использовать один из коротких символов, например +
(Сокращенное от {1,}
, что означает хотя бы один) или *
(имеется в виду любое число, включая ноль). С этим знанием вы можете сопоставить что угодно с .*
.
По умолчанию выражения будут соответствовать максимально возможному шаблону (известен как жадный). Вы можете изменить это с помощью модификатора ?
. Таким образом, .*?
будет соответствовать чему угодно, но принимать кратчайший возможный образец. Затем его можно использовать для сопоставления любому значению с разделителями, например:
~<foo>.*?</foo>~
Обратите внимание, что я использую ~
в качестве разделителя, чтобы избежать экранирования /
в выражении. Стандартом является использование /
в качестве разделителя, в этом случае выражение выглядело бы так:
/<foo>.*?<\/foo>/
В целом, вышесказанное является плохой практикой, поскольку гораздо лучше сопоставлять отрицательный класс символов, чем точку, но для простоты просто игнорируйте это до тех пор, пока не получите основы под своей оболочкой. Это будет работать в большинстве случаев. В частности, поскольку .
не соответствует символу новой строки, это не будет работать, если содержимое содержит символ новой строки. Если вам это нужно, вы можете сделать одно из двух: либо добавьте к выражению модификатор , либо замените .
классом символов, включающим символы новой строки. Например, [\s\S]
(имеется в виду символ пробела или - символ без пробела, который совпадает с чем-либо). Вот так выглядело бы выражение:
~<foo>.*?</foo>~s
Или:
~<foo>[\s\S]*?</foo>~
Чтобы все это заработало, давайте передадим это функции preg_replace
:
echo preg_replace('~<foo>.*?</foo>~s', '<foo>Lorem Ipsum</foo>', $input);
Если ваши имена тегов являются переменными, вы можете создать выражение, как если бы вы использовали SQL-запрос. Как и в SQL, вам нужно экранировать определенные символы. Для этого используйте preg_quote
:
function swapText($tagname, $replacement_text, $input) {
$tagname_escaped = preg_quote($tagname, '~');
return preg_replace(
'~<' . $tagname_escaped . '>.*?</' . $tagname_escaped . '>~s',
'<' . $tagname . '>' . $replacement_text . '</' . $tagname . '>',
$input);
}