Как правильно составить регулярное выражение?

Добрый день. Есть такой код: <br/> <pre><code class="php">$xml = file_get_contents($url);
  • 31 мая 2026 г. 8:00
Ответы на вопрос 3
Добрый день. Надо понять, что именно вы хотите вытащить из $xml — конкретный тег, атрибут, все элементы item и т.п. Пока этого нет, приведу общие рекомендации и несколько готовых примеров (а ещё — более правильный путь для XML).

1) Совет: не парсить сложный XML регулярками — используйте SimpleXML или DOMDocument. Регулярки ломаются на вложенности, namespace и т. п.

Пример с SimpleXML:
$xml = file_get_contents($url);
$sx = simplexml_load_string($xml);
foreach ($sx->channel->item as $item) {
    echo (string)$item->title . "\n";
}

2) Если всё же нужна регулярка (для простых случаев), основные моменты:
- В PHP регулярки окружайте разделителем, например '#...#'.
- Флаг s разрешает точке матчить переводы строк, i — нечувствительность к регистру, u — UTF-8.
- Берите захватывающие группы ( ) и потом смотрите $matches[1].

Примеры:

a) Вытянуть содержимое тега <title>...</title> (включая переносы строк):
$re = '#<title[^>]*>(.*?)</title>#siu';
if (preg_match_all($re, $xml, $m)) {
    // $m[1] — массив содержимого title
    print_r($m[1]);
}

Разбор: <title[^>]*> — открывающий тег, (.*?) — минимальный захват содержимого, </title> — закрывающий. s — чтобы . брал переводы строк, u — UTF-8.

b) Вытянуть атрибут value="...":
$re = '#<tag[^>]*\bvalue="([^"]*)"[^>]*>#siu';
if (preg_match_all($re, $xml, $m)) {
    print_r($m[1]); // массив значений атрибута value
}

c) Захватить каждый <item>...</item>:
$re = '#<item\b[^>]*>(.*?)</item>#siu';
preg_match_all($re, $xml, $m);
$items = $m[1];

3) Если теги содержат вложенные теги и сложную структуру — используйте DOM/SimpleXML или XMLReader.

Пример с DOMDocument:
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadXML($xml);
foreach ($doc->getElementsByTagName('item') as $item) {
    $titles = $item->getElementsByTagName('title');
    if ($titles->length) echo $titles->item(0)->nodeValue . "\n";
}

Если подскажете кусок реального $xml и что конкретно вы хотите получить (пример входа и ожидаемый результат), я напишу точную регулярку или готовый SimpleXML/DOM-код.
preg_match_all так и работает — отдельный массив на каждую группу. Склеиваешь руками: <br/> <br/> <pre><code>$result = [];
foreach ($matches[1] as $i =&gt; $name) {
    if ($matches[2][$i] !== '') {
        $result[] = $name . ', ' . $matches[2][$i];
    }
}
$data['params'] = array_unique($result);</code></pre>
Использовать регулярные выражение - это обязательное условие? <br/> <br/> Намного надежнее и правильнее будет решить эту задачу с помощью <a href="https://www.php.net/manual/ru/class.domdocument.php" rel="nofollow">DOMDocument</a> <br/> <pre><code class="php">$xml = file_get_contents($url);
$dom = new DOMDocument();
$dom-&gt;loadXML($xml);
$params = $dom-&gt;getElementsByTagName('param');
$data['params'] = []; 
foreach ($params as $param) {
    if ($param-&gt;hasAttribute('unit') &amp;&amp; trim($param-&gt;getAttribute('unit')) !== '') {
        // Ищем нужные данные в xml документе 
        $name = $param-&gt;getAttribute('name');
        $unit = $param-&gt;getAttribute('unit');        
        // Собираем строку и добавляем в массив
        $data['params'][] = $name . ', ' . $unit;
    }
}
$data['params'] = array_unique($data['params']);</code></pre>
Похожие вопросы